Revert r3667 and r3665
Review URL: https://webrtc-codereview.appspot.com/1199004

git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@3668 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/engine_configurations.h b/engine_configurations.h
index f3d2a46..67effa0 100644
--- a/engine_configurations.h
+++ b/engine_configurations.h
@@ -109,6 +109,7 @@
 #define WEBRTC_VIDEO_ENGINE_CODEC_API
 #define WEBRTC_VIDEO_ENGINE_ENCRYPTION_API
 #define WEBRTC_VIDEO_ENGINE_IMAGE_PROCESS_API
+#define WEBRTC_VIDEO_ENGINE_NETWORK_API
 #define WEBRTC_VIDEO_ENGINE_RENDER_API
 #define WEBRTC_VIDEO_ENGINE_RTP_RTCP_API
 #define WEBRTC_VIDEO_ENGINE_EXTERNAL_CODEC_API
diff --git a/modules/modules.gyp b/modules/modules.gyp
index 1671c13..837d551 100644
--- a/modules/modules.gyp
+++ b/modules/modules.gyp
@@ -27,6 +27,7 @@
     'pacing/pacing.gypi',
     'remote_bitrate_estimator/remote_bitrate_estimator.gypi',
     'rtp_rtcp/source/rtp_rtcp.gypi',
+    'udp_transport/source/udp_transport.gypi',
     'utility/source/utility.gypi',
     'video_coding/codecs/i420/main/source/i420.gypi',
     'video_coding/main/source/video_coding.gypi',
diff --git a/modules/udp_transport/OWNERS b/modules/udp_transport/OWNERS
new file mode 100644
index 0000000..3b2a444
--- /dev/null
+++ b/modules/udp_transport/OWNERS
@@ -0,0 +1,4 @@
+pwestin@webrtc.org

+henrikg@webrtc.org

+mallinath@webrtc.org

+tomasl@webrtc.org
\ No newline at end of file
diff --git a/test/udp_transport/udp_transport.h b/modules/udp_transport/interface/udp_transport.h
similarity index 84%
rename from test/udp_transport/udp_transport.h
rename to modules/udp_transport/interface/udp_transport.h
index 8427c7e..2ca4eb8 100644
--- a/test/udp_transport/udp_transport.h
+++ b/modules/udp_transport/interface/udp_transport.h
@@ -8,11 +8,12 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#ifndef WEBRTC_TEST_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_
-#define WEBRTC_TEST_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_
+#ifndef WEBRTC_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_
+#define WEBRTC_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_
 
-#include "webrtc/common_types.h"
-#include "webrtc/typedefs.h"
+#include "common_types.h"
+#include "module.h"
+#include "typedefs.h"
 
 /*
  *  WARNING
@@ -21,6 +22,7 @@
  *
  */
 
+
 #define SS_MAXSIZE 128
 #define SS_ALIGNSIZE (sizeof (WebRtc_UWord64))
 #define SS_PAD1SIZE  (SS_ALIGNSIZE - sizeof(WebRtc_Word16))
@@ -29,84 +31,94 @@
 
 // BSD requires use of HAVE_STRUCT_SOCKADDR_SA_LEN
 namespace webrtc {
-struct SocketAddressIn {
-  // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
+struct SocketAddressIn
+{
+    // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-  WebRtc_Word8      sin_length;
-  WebRtc_Word8      sin_family;
+    WebRtc_Word8      sin_length;
+    WebRtc_Word8      sin_family;
 #else
-  WebRtc_Word16     sin_family;
+    WebRtc_Word16     sin_family;
 #endif
-  WebRtc_UWord16    sin_port;
-  WebRtc_UWord32    sin_addr;
-  WebRtc_Word8      sin_zero[8];
+    WebRtc_UWord16    sin_port;
+    WebRtc_UWord32    sin_addr;
+    WebRtc_Word8      sin_zero[8];
 };
 
-struct Version6InAddress {
-  union {
-    WebRtc_UWord8     _s6_u8[16];
-    WebRtc_UWord32    _s6_u32[4];
-    WebRtc_UWord64    _s6_u64[2];
-  } Version6AddressUnion;
+struct Version6InAddress
+{
+    union
+    {
+        WebRtc_UWord8     _s6_u8[16];
+        WebRtc_UWord32    _s6_u32[4];
+        WebRtc_UWord64    _s6_u64[2];
+    } Version6AddressUnion;
 };
 
-struct SocketAddressInVersion6 {
-  // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
+struct SocketAddressInVersion6
+{
+    // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-  WebRtc_Word8      sin_length;
-  WebRtc_Word8      sin_family;
+    WebRtc_Word8      sin_length;
+    WebRtc_Word8      sin_family;
 #else
-  WebRtc_Word16     sin_family;
+    WebRtc_Word16     sin_family;
 #endif
-  // Transport layer port number.
-  WebRtc_UWord16 sin6_port;
-  // IPv6 traffic class and flow info or ip4 address.
-  WebRtc_UWord32 sin6_flowinfo;
-  // IPv6 address
-  struct Version6InAddress sin6_addr;
-  // Set of interfaces for a scope.
-  WebRtc_UWord32 sin6_scope_id;
+    // Transport layer port number.
+    WebRtc_UWord16 sin6_port;
+    // IPv6 traffic class and flow info or ip4 address.
+    WebRtc_UWord32 sin6_flowinfo;
+    // IPv6 address
+    struct Version6InAddress sin6_addr;
+    // Set of interfaces for a scope.
+    WebRtc_UWord32 sin6_scope_id;
 };
 
-struct SocketAddressStorage {
-  // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
+struct SocketAddressStorage
+{
+    // sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-  WebRtc_Word8   sin_length;
-  WebRtc_Word8   sin_family;
+    WebRtc_Word8   sin_length;
+    WebRtc_Word8   sin_family;
 #else
-  WebRtc_Word16  sin_family;
+    WebRtc_Word16  sin_family;
 #endif
-  WebRtc_Word8   __ss_pad1[SS_PAD1SIZE];
-  WebRtc_UWord64 __ss_align;
-  WebRtc_Word8   __ss_pad2[SS_PAD2SIZE];
+    WebRtc_Word8   __ss_pad1[SS_PAD1SIZE];
+    WebRtc_UWord64 __ss_align;
+    WebRtc_Word8   __ss_pad2[SS_PAD2SIZE];
 };
 
-struct SocketAddress {
-  union {
-    struct SocketAddressIn _sockaddr_in;
-    struct SocketAddressInVersion6 _sockaddr_in6;
-    struct SocketAddressStorage _sockaddr_storage;
-  };
+struct SocketAddress
+{
+    union
+    {
+        struct SocketAddressIn _sockaddr_in;
+        struct SocketAddressInVersion6 _sockaddr_in6;
+        struct SocketAddressStorage _sockaddr_storage;
+    };
 };
 
 // Callback class that receives packets from UdpTransport.
-class UdpTransportData {
- public:
-  virtual ~UdpTransportData()  {};
+class UdpTransportData
+{
+public:
+    virtual ~UdpTransportData()  {};
 
-  virtual void IncomingRTPPacket(const WebRtc_Word8* incomingRtpPacket,
-                                 const WebRtc_Word32 rtpPacketLength,
-                                 const char* fromIP,
-                                 const WebRtc_UWord16 fromPort) = 0;
+    virtual void IncomingRTPPacket(const WebRtc_Word8* incomingRtpPacket,
+                                   const WebRtc_Word32 rtpPacketLength,
+                                   const char* fromIP,
+                                   const WebRtc_UWord16 fromPort) = 0;
 
-  virtual void IncomingRTCPPacket(const WebRtc_Word8* incomingRtcpPacket,
-                                  const WebRtc_Word32 rtcpPacketLength,
-                                  const char* fromIP,
-                                  const WebRtc_UWord16 fromPort) = 0;
+    virtual void IncomingRTCPPacket(const WebRtc_Word8* incomingRtcpPacket,
+                                    const WebRtc_Word32 rtcpPacketLength,
+                                    const char* fromIP,
+                                    const WebRtc_UWord16 fromPort) = 0;
 };
 
-class UdpTransport : public Transport {
- public:
+
+class UdpTransport : public Module, public Transport
+{
+public:
     enum
     {
         kIpAddressVersion6Length = 64,
@@ -377,7 +389,6 @@
     // is interptreted as IPv6.
     static bool IsIpAddressValid(const char* ipaddr, const bool ipV6);
 };
-
 } // namespace webrtc
 
-#endif // WEBRTC_TEST_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_
+#endif // WEBRTC_MODULES_UDP_TRANSPORT_INTERFACE_UDP_TRANSPORT_H_
diff --git a/test/udp_transport/Android.mk b/modules/udp_transport/source/Android.mk
similarity index 100%
rename from test/udp_transport/Android.mk
rename to modules/udp_transport/source/Android.mk
diff --git a/test/udp_transport/traffic_control_win.cc b/modules/udp_transport/source/traffic_control_windows.cc
similarity index 98%
rename from test/udp_transport/traffic_control_win.cc
rename to modules/udp_transport/source/traffic_control_windows.cc
index fcafe7c..09038c0 100644
--- a/test/udp_transport/traffic_control_win.cc
+++ b/modules/udp_transport/source/traffic_control_windows.cc
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "traffic_control_win.h"
+#include "traffic_control_windows.h"
 
 #include <assert.h>
 
diff --git a/test/udp_transport/traffic_control_win.h b/modules/udp_transport/source/traffic_control_windows.h
similarity index 100%
rename from test/udp_transport/traffic_control_win.h
rename to modules/udp_transport/source/traffic_control_windows.h
diff --git a/test/udp_transport/udp_socket2_manager_win.cc b/modules/udp_transport/source/udp_socket2_manager_windows.cc
similarity index 98%
rename from test/udp_transport/udp_socket2_manager_win.cc
rename to modules/udp_transport/source/udp_socket2_manager_windows.cc
index 94dddc1..32863d3 100644
--- a/test/udp_transport/udp_socket2_manager_win.cc
+++ b/modules/udp_transport/source/udp_socket2_manager_windows.cc
@@ -8,13 +8,13 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "udp_socket2_manager_win.h"
+#include "udp_socket2_manager_windows.h"
 
 #include <assert.h>
 #include <stdio.h>
 
 #include "aligned_malloc.h"
-#include "udp_socket2_win.h"
+#include "udp_socket2_windows.h"
 
 namespace webrtc {
 WebRtc_UWord32 UdpSocket2ManagerWindows::_numOfActiveManagers = 0;
diff --git a/test/udp_transport/udp_socket2_manager_win.h b/modules/udp_transport/source/udp_socket2_manager_windows.h
similarity index 98%
rename from test/udp_transport/udp_socket2_manager_win.h
rename to modules/udp_transport/source/udp_socket2_manager_windows.h
index 8cf5ebc..782cb41 100644
--- a/test/udp_transport/udp_socket2_manager_win.h
+++ b/modules/udp_transport/source/udp_socket2_manager_windows.h
@@ -22,7 +22,7 @@
 #include "event_wrapper.h"
 #include "list_wrapper.h"
 #include "thread_wrapper.h"
-#include "udp_socket2_win.h"
+#include "udp_socket2_windows.h"
 #include "udp_socket_manager_wrapper.h"
 
 #define MAX_IO_BUFF_SIZE 1600
diff --git a/test/udp_transport/udp_socket2_win.cc b/modules/udp_transport/source/udp_socket2_windows.cc
similarity index 98%
rename from test/udp_transport/udp_socket2_win.cc
rename to modules/udp_transport/source/udp_socket2_windows.cc
index 0cb0c61..2362cdd 100644
--- a/test/udp_transport/udp_socket2_win.cc
+++ b/modules/udp_transport/source/udp_socket2_windows.cc
@@ -8,14 +8,14 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "udp_socket2_win.h"
+#include "udp_socket2_windows.h"
 
 #include <assert.h>
 #include <stdlib.h>
 #include <winsock2.h>
 
-#include "traffic_control_win.h"
-#include "udp_socket2_manager_win.h"
+#include "traffic_control_windows.h"
+#include "udp_socket2_manager_windows.h"
 
 #pragma warning(disable : 4311)
 
diff --git a/test/udp_transport/udp_socket2_win.h b/modules/udp_transport/source/udp_socket2_windows.h
similarity index 98%
rename from test/udp_transport/udp_socket2_win.h
rename to modules/udp_transport/source/udp_socket2_windows.h
index e63f277..8cc46ee 100644
--- a/test/udp_transport/udp_socket2_win.h
+++ b/modules/udp_transport/source/udp_socket2_windows.h
@@ -27,7 +27,7 @@
 #include "rw_lock_wrapper.h"
 #include "trace.h"
 #include "udp_socket_wrapper.h"
-#include "udp_socket2_manager_win.h"
+#include "udp_socket2_manager_windows.h"
 
 namespace webrtc {
 class UdpSocket2ManagerWindows;
diff --git a/test/udp_transport/udp_socket_manager_posix.cc b/modules/udp_transport/source/udp_socket_manager_posix.cc
similarity index 100%
rename from test/udp_transport/udp_socket_manager_posix.cc
rename to modules/udp_transport/source/udp_socket_manager_posix.cc
diff --git a/test/udp_transport/udp_socket_manager_posix.h b/modules/udp_transport/source/udp_socket_manager_posix.h
similarity index 100%
rename from test/udp_transport/udp_socket_manager_posix.h
rename to modules/udp_transport/source/udp_socket_manager_posix.h
diff --git a/test/udp_transport/udp_socket_manager_unittest.cc b/modules/udp_transport/source/udp_socket_manager_unittest.cc
similarity index 100%
rename from test/udp_transport/udp_socket_manager_unittest.cc
rename to modules/udp_transport/source/udp_socket_manager_unittest.cc
diff --git a/test/udp_transport/udp_socket_manager_wrapper.cc b/modules/udp_transport/source/udp_socket_manager_wrapper.cc
similarity index 97%
rename from test/udp_transport/udp_socket_manager_wrapper.cc
rename to modules/udp_transport/source/udp_socket_manager_wrapper.cc
index a1fae5a..37388be 100644
--- a/test/udp_transport/udp_socket_manager_wrapper.cc
+++ b/modules/udp_transport/source/udp_socket_manager_wrapper.cc
@@ -14,7 +14,7 @@
 
 #ifdef _WIN32
 #include "fix_interlocked_exchange_pointer_win.h"
-#include "udp_socket2_manager_win.h"
+#include "udp_socket2_manager_windows.h"
 #else
 #include "udp_socket_manager_posix.h"
 #endif
diff --git a/test/udp_transport/udp_socket_manager_wrapper.h b/modules/udp_transport/source/udp_socket_manager_wrapper.h
similarity index 100%
rename from test/udp_transport/udp_socket_manager_wrapper.h
rename to modules/udp_transport/source/udp_socket_manager_wrapper.h
diff --git a/test/udp_transport/udp_socket_posix.cc b/modules/udp_transport/source/udp_socket_posix.cc
similarity index 100%
rename from test/udp_transport/udp_socket_posix.cc
rename to modules/udp_transport/source/udp_socket_posix.cc
diff --git a/test/udp_transport/udp_socket_posix.h b/modules/udp_transport/source/udp_socket_posix.h
similarity index 100%
rename from test/udp_transport/udp_socket_posix.h
rename to modules/udp_transport/source/udp_socket_posix.h
diff --git a/test/udp_transport/udp_socket_wrapper.cc b/modules/udp_transport/source/udp_socket_wrapper.cc
similarity index 98%
rename from test/udp_transport/udp_socket_wrapper.cc
rename to modules/udp_transport/source/udp_socket_wrapper.cc
index 8948987..6445e76 100644
--- a/test/udp_transport/udp_socket_wrapper.cc
+++ b/modules/udp_transport/source/udp_socket_wrapper.cc
@@ -18,7 +18,7 @@
 #include "udp_socket_manager_wrapper.h"
 
 #if defined(_WIN32)
-    #include "udp_socket2_win.h"
+    #include "udp_socket2_windows.h"
 #else
     #include "udp_socket_posix.h"
 #endif
diff --git a/test/udp_transport/udp_socket_wrapper.h b/modules/udp_transport/source/udp_socket_wrapper.h
similarity index 100%
rename from test/udp_transport/udp_socket_wrapper.h
rename to modules/udp_transport/source/udp_socket_wrapper.h
diff --git a/test/udp_transport/udp_socket_wrapper_unittest.cc b/modules/udp_transport/source/udp_socket_wrapper_unittest.cc
similarity index 94%
rename from test/udp_transport/udp_socket_wrapper_unittest.cc
rename to modules/udp_transport/source/udp_socket_wrapper_unittest.cc
index 0d6c37d..2489604 100644
--- a/test/udp_transport/udp_socket_wrapper_unittest.cc
+++ b/modules/udp_transport/source/udp_socket_wrapper_unittest.cc
@@ -22,8 +22,8 @@
 
 #include "gtest/gtest.h"
 #include "gmock/gmock.h"
-#include "webrtc/test/udp_transport/udp_socket_wrapper.h"
-#include "webrtc/test/udp_transport/udp_socket_manager_wrapper.h"
+#include "modules/udp_transport/source/udp_socket_wrapper.h"
+#include "modules/udp_transport/source/udp_socket_manager_wrapper.h"
 
 using ::testing::_;
 using ::testing::Return;
diff --git a/modules/udp_transport/source/udp_transport.gypi b/modules/udp_transport/source/udp_transport.gypi
new file mode 100644
index 0000000..a73a587
--- /dev/null
+++ b/modules/udp_transport/source/udp_transport.gypi
@@ -0,0 +1,114 @@
+# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+#
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file in the root of the source
+# tree. An additional intellectual property rights grant can be found
+# in the file PATENTS.  All contributing project authors may
+# be found in the AUTHORS file in the root of the source tree.
+
+{
+  'targets': [
+    {
+      'target_name': 'udp_transport',
+      'type': 'static_library',
+      'dependencies': [
+        '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
+      ],
+      'include_dirs': [
+        '../interface',
+        '../../interface',
+      ],
+      'direct_dependent_settings': {
+        'include_dirs': [
+          '../interface',
+          '../../interface',
+        ],
+      },
+      'sources': [
+        # PLATFORM INDEPENDENT SOURCE FILES
+        '../interface/udp_transport.h',
+        'udp_transport_impl.cc',
+        'udp_socket_wrapper.cc',
+        'udp_socket_manager_wrapper.cc',
+        'udp_transport_impl.h',
+        'udp_socket_wrapper.h',
+        'udp_socket_manager_wrapper.h',
+        # PLATFORM SPECIFIC SOURCE FILES - Will be filtered below
+        # Posix (Linux/Mac)
+        'udp_socket_posix.cc',
+        'udp_socket_posix.h',
+        'udp_socket_manager_posix.cc',
+        'udp_socket_manager_posix.h',
+        # Windows
+        'udp_socket2_manager_windows.cc',
+        'udp_socket2_manager_windows.h',
+        'udp_socket2_windows.cc',
+        'udp_socket2_windows.h',
+        'traffic_control_windows.cc',
+        'traffic_control_windows.h',
+      ], # source
+      'conditions': [
+        # DEFINE PLATFORM SPECIFIC SOURCE FILES
+        ['os_posix==0', {
+          'sources!': [
+            'udp_socket_posix.cc',
+            'udp_socket_posix.h',
+            'udp_socket_manager_posix.cc',
+            'udp_socket_manager_posix.h',
+          ],
+        }],
+        ['OS!="win"', {
+          'sources!': [
+            'udp_socket2_manager_windows.cc',
+            'udp_socket2_manager_windows.h',
+            'udp_socket2_windows.cc',
+            'udp_socket2_windows.h',
+            'traffic_control_windows.cc',
+            'traffic_control_windows.h',
+          ],
+        }],
+        ['OS=="linux"', {
+          'cflags': [
+            '-fno-strict-aliasing',
+          ],
+        }],
+        ['OS=="mac"', {
+          'xcode_settings': {
+            'OTHER_CPLUSPLUSFLAGS': [ '-fno-strict-aliasing' ],
+          },
+        }],
+      ] # conditions
+    },
+  ], # targets
+  'conditions': [
+    ['include_tests==1', {
+      'targets': [
+        {
+          'target_name': 'udp_transport_unittests',
+          'type': 'executable',
+          'dependencies': [
+            'udp_transport',
+            '<(DEPTH)/testing/gtest.gyp:gtest',
+            '<(DEPTH)/testing/gmock.gyp:gmock',
+            '<(webrtc_root)/test/test.gyp:test_support_main',
+          ],
+          'sources': [
+            'udp_transport_unittest.cc',
+            'udp_socket_manager_unittest.cc',
+            'udp_socket_wrapper_unittest.cc',
+          ],
+          # Disable warnings to enable Win64 build, issue 1323.
+          'msvs_disabled_warnings': [
+            4267,  # size_t to int truncation.
+          ],
+        }, # udp_transport_unittests
+      ], # targets
+    }], # include_tests
+  ], # conditions
+}
+
+# Local Variables:
+# tab-width:2
+# indent-tabs-mode:nil
+# End:
+# vim: set expandtab tabstop=2 shiftwidth=2:
diff --git a/test/udp_transport/udp_transport_impl.cc b/modules/udp_transport/source/udp_transport_impl.cc
similarity index 98%
rename from test/udp_transport/udp_transport_impl.cc
rename to modules/udp_transport/source/udp_transport_impl.cc
index 875ce93..b7ded87 100644
--- a/test/udp_transport/udp_transport_impl.cc
+++ b/modules/udp_transport/source/udp_transport_impl.cc
@@ -179,6 +179,44 @@
                  __FUNCTION__);
 }
 
+WebRtc_Word32 UdpTransportImpl::ChangeUniqueId(const WebRtc_Word32 id)
+{
+
+    CriticalSectionScoped cs(_crit);
+    _id = id;
+    if(_mgr)
+    {
+        _mgr->ChangeUniqueId(id);
+    }
+    if(_ptrRtpSocket)
+    {
+        _ptrRtpSocket->ChangeUniqueId(id);
+    }
+    if(_ptrRtcpSocket)
+    {
+        _ptrRtcpSocket->ChangeUniqueId(id);
+    }
+    if(_ptrSendRtpSocket)
+    {
+        _ptrSendRtpSocket->ChangeUniqueId(id);
+    }
+    if(_ptrSendRtcpSocket)
+    {
+        _ptrSendRtcpSocket->ChangeUniqueId(id);
+    }
+    return 0;
+}
+
+WebRtc_Word32 UdpTransportImpl::TimeUntilNextProcess()
+{
+    return 100;
+}
+
+WebRtc_Word32 UdpTransportImpl::Process()
+{
+    return 0;
+}
+
 UdpTransport::ErrorCode UdpTransportImpl::LastError() const
 {
     return _lastError;
@@ -1360,7 +1398,7 @@
     {
         SocketAddress stLclName;
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-        stLclName.sin_lenght = 0;
+        stLclName.sin_length = 0;
         stLclName.sin_family = PF_INET6;
 #else
         stLclName._sockaddr_storage.sin_family = PF_INET6;
@@ -2523,7 +2561,7 @@
     req.r.ifa_family = AF_INET6;
 
     // Fill up all the attributes for the rtnetlink header.
-    // The lenght is very important. 16 signifies the ipv6 address.
+    // The length is very important. 16 signifies the ipv6 address.
     rta = (struct rtattr*)(((char*)&req) + NLMSG_ALIGN(req.n.nlmsg_len));
     rta->rta_len = RTA_LENGTH(16);
 
diff --git a/test/udp_transport/udp_transport_impl.h b/modules/udp_transport/source/udp_transport_impl.h
similarity index 97%
rename from test/udp_transport/udp_transport_impl.h
rename to modules/udp_transport/source/udp_transport_impl.h
index e2fa795..9f4fd9f 100644
--- a/test/udp_transport/udp_transport_impl.h
+++ b/modules/udp_transport/source/udp_transport_impl.h
@@ -42,6 +42,11 @@
                      UdpSocketManager* socket_manager);
     virtual ~UdpTransportImpl();
 
+    // Module functions
+    virtual WebRtc_Word32 ChangeUniqueId(const WebRtc_Word32 id);
+    virtual WebRtc_Word32 TimeUntilNextProcess();
+    virtual WebRtc_Word32 Process();
+
     // UdpTransport functions
     virtual WebRtc_Word32 InitializeSendSockets(
         const char* ipAddr,
diff --git a/test/udp_transport/udp_transport_unittest.cc b/modules/udp_transport/source/udp_transport_unittest.cc
similarity index 96%
rename from test/udp_transport/udp_transport_unittest.cc
rename to modules/udp_transport/source/udp_transport_unittest.cc
index 243cbda..3125e2e 100644
--- a/test/udp_transport/udp_transport_unittest.cc
+++ b/modules/udp_transport/source/udp_transport_unittest.cc
@@ -10,14 +10,14 @@
 
 #include <vector>
 
+#include "udp_transport.h"
 #include "gmock/gmock.h"
 #include "gtest/gtest.h"
-#include "webrtc/test/udp_transport/udp_transport.h"
 // We include the implementation header file to get at the dependency-injecting
 // constructor.
-#include "webrtc/test/udp_transport/udp_transport_impl.h"
+#include "udp_transport_impl.h"
 // We must mock the socket manager, for which we need its definition.
-#include "webrtc/test/udp_transport/udp_socket_manager_wrapper.h"
+#include "udp_socket_manager_wrapper.h"
 
 using ::testing::_;
 using ::testing::Return;
diff --git a/modules/udp_transport/test/SocketManagerTest.cc b/modules/udp_transport/test/SocketManagerTest.cc
new file mode 100644
index 0000000..03119be
--- /dev/null
+++ b/modules/udp_transport/test/SocketManagerTest.cc
@@ -0,0 +1,449 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include <cassert>
+#include <iostream>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <tchar.h>
+#else
+#include <stdio.h>
+#define Sleep(x) usleep(x*1000)
+#endif
+
+#include "udp_transport.h"
+#include "common_types.h"
+#include "trace.h"
+
+//#define QOS_TEST
+//#define QOS_TEST_WITH_OVERRIDE // require admin on Win7
+//#define TOS_TEST               // require admin on Win7
+//#define TOS_TEST_USING_SETSOCKOPT
+//#define PCP_TEST
+
+class UdpTransportDataA: public UdpTransportData
+{
+public:
+    UdpTransportDataA() :
+        _counterRTP(0),
+        _counterRTCP(0)
+    {
+    };
+    virtual void IncomingRTPPacket(const WebRtc_Word8* incommingRtpPacket,
+                                   const WebRtc_Word32 rtpPacketLength,
+                                   const char* fromIP,
+                                   const WebRtc_UWord16 fromPort)
+    {
+        _counterRTP++;
+    };
+
+    virtual void IncomingRTCPPacket(const WebRtc_Word8* incommingRtcpPacket,
+                                    const WebRtc_Word32 rtcpPacketLength,
+                                    const char* fromIP,
+                                    const WebRtc_UWord16 fromPort)
+    {
+        _counterRTCP++;
+    };
+    WebRtc_UWord32    _counterRTP;
+    WebRtc_UWord32    _counterRTCP;
+};
+
+class UdpTransportDataB: public UdpTransportData
+{
+public:
+    UdpTransportDataB() :
+        _counterRTP(0),
+        _counterRTCP(0)
+    {
+    };
+    virtual void IncomingRTPPacket(const WebRtc_Word8* incommingRtpPacket,
+                                   const WebRtc_Word32 rtpPacketLength,
+                                   const char* fromIP,
+                                   const WebRtc_UWord16 fromPort)
+    {
+        _counterRTP++;
+    };
+
+    virtual void IncomingRTCPPacket(const WebRtc_Word8* incommingRtcpPacket,
+                                    const WebRtc_Word32 rtcpPacketLength,
+                                    const char* fromIP,
+                                    const WebRtc_UWord16 fromPort)
+    {
+        _counterRTCP++;
+    };
+    WebRtc_UWord32    _counterRTP;
+    WebRtc_UWord32    _counterRTCP;
+};
+
+#ifdef _WIN32
+int _tmain(int argc, _TCHAR* argv[])
+#else
+int main(int argc, char* argv[])
+#endif
+{
+    Trace::CreateTrace();
+    Trace::SetTraceFile("testTrace.txt");
+    Trace::SetEncryptedTraceFile("testTraceDebug.txt");
+    Trace::SetLevelFilter(webrtc::kTraceAll);
+
+    printf("Start UdpTransport test\n");
+
+    WebRtc_UWord8 numberOfSocketThreads = 5;
+    UdpTransport* client1 = UdpTransport::Create(1,numberOfSocketThreads,NULL);
+    numberOfSocketThreads = 0;
+    UdpTransport* client2 = UdpTransport::Create(2,numberOfSocketThreads,NULL);
+    assert(5 == numberOfSocketThreads);
+
+    UdpTransportDataA* client1Callback = new UdpTransportDataA();
+    UdpTransportDataB* client2Callback = new UdpTransportDataB();
+
+    WebRtc_UWord32 localIP = 0;
+    char localIPAddr[64];
+    assert( 0 == client1->LocalHostAddress(localIP)); // network host order aka big-endian
+
+    sprintf(localIPAddr,"%lu.%lu.%lu.%lu",(localIP>>24)& 0x0ff,(localIP>>16)& 0x0ff ,(localIP>>8)& 0x0ff, localIP & 0x0ff);
+    printf("\tLocal IP:%s\n", localIPAddr);
+
+    char localIPV6[16];
+    char localIPAddrV6[128];
+    if( 0 == client1->LocalHostAddressIPV6(localIPV6))
+    {
+        sprintf(localIPAddrV6,"%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x", localIPV6[0],localIPV6[1],localIPV6[2],localIPV6[3],localIPV6[4],localIPV6[5],localIPV6[6],localIPV6[7], localIPV6[8],localIPV6[9],localIPV6[10],localIPV6[11],localIPV6[12],localIPV6[13],localIPV6[14],localIPV6[15]);
+        printf("\tLocal IPV6:%s\n", localIPAddrV6);
+    }
+
+    char test[9] = "testtest";
+    assert( 0 == client1->InitializeReceiveSockets(client1Callback,1234, localIPAddr));
+
+#if defined QOS_TEST_WITH_OVERRIDE || defined QOS_TEST || defined TOS_TEST || defined TOS_TEST_USING_SETSOCKOPT
+    assert( -1 == client1->SetQoS(true, 3, 1000));  //  should fail
+    assert( 0 == client1->InitializeSendSockets("192.168.200.1", 1236,1237));
+#else
+    assert( 0 == client1->InitializeSendSockets(localIPAddr, 1236,1237));
+#endif
+    assert( 0 == client1->StartReceiving(20));
+
+    assert( 0 == client2->InitializeReceiveSockets(client2Callback,1236));
+    assert( 0 == client2->InitializeSendSockets(localIPAddr, 1234,1235));
+    assert( 0 == client2->StartReceiving(20));
+
+    Sleep(10);
+
+#ifdef TOS_TEST
+    // note: you need to have QOS installed on your interface for this test
+    // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1
+    assert( 0 == client1->SetToS(2));
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+    Sleep(10);
+    assert( 0 == client1->SetToS(3));
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+    Sleep(10);
+    assert( 0 == client1->SetToS(0));
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+
+    printf("Tested TOS  \n");
+    Sleep(5000);
+    return 0;
+#endif
+
+#ifdef TOS_TEST_USING_SETSOCKOPT
+    // note: you need to have QOS installed on your interface for this test
+    // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1
+    assert( 0 == client1->SetToS(2, true));
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+    Sleep(10);
+    assert( 0 == client1->SetToS(3, true));
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+    Sleep(10);
+    assert( 0 == client1->SetToS(0, true));
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+
+    printf("Tested TOS using setsockopt \n");
+    Sleep(5000);
+    return 0;
+#endif
+
+#ifdef QOS_TEST
+    // note: you need to have QOS installed on your interface for this test
+    // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1
+    assert( 0 == client1->SetQoS(true, 2, 1000));  // SERVICETYPE_CONTROLLEDLOAD 2
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+    Sleep(10);
+    assert( 0 == client1->SetQoS(true, 3, 1000));  // SERVICETYPE_GUARANTEED 3
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+    Sleep(10);
+    assert( 0 == client1->SetQoS(false, 0));  //
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+
+    printf("Tested QOS  \n");
+    Sleep(5000);
+    return 0;
+#endif
+
+#ifdef QOS_TEST_WITH_OVERRIDE
+    // note: you need to have QOS installed on your interface for this test
+    // test by doing a ethereal sniff and filter out packets with ip.dst == 192.168.200.1
+    assert( 0 == client1->SetQoS(true, 2, 1000, 1));  // SERVICETYPE_CONTROLLEDLOAD 2
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+    Sleep(10);
+    assert( 0 == client1->SetQoS(true, 2, 1000, 2));  // SERVICETYPE_GUARANTEED 3
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+    Sleep(10);
+    assert( 0 == client1->SetQoS(false, 0));  //
+    Sleep(10);
+    assert( 9 == client1->SendPacket(-1, test, 9));
+    printf("Tested QOS with override \n");
+    Sleep(5000);
+    return 0;
+#endif
+
+#ifdef PCP_TEST
+    // Note: We currently don't know how to test that the bits are actually set in the frame,
+    // this test simply tests the API and that we can send a packet after setting PCP.
+    assert( -1 == client1->SetPCP(-1)); // should fail
+    assert( -1 == client1->SetPCP(8)); // should fail
+    printf("Setting PCP to 7 returned %d \n", client1->SetPCP(7));
+    printf("(Failing is normal, requires the CAP_NET_ADMIN capability to succeed.) \n");
+    Sleep(10);
+    for (int pcp = 6; pcp >= 0; --pcp)
+    {
+        assert( 0 == client1->SetPCP(pcp));
+        Sleep(10);
+        assert( 9 == client1->SendPacket(-1, test, 9));
+    }
+    printf("Tested PCP \n");
+    Sleep(5000);
+    return 0;
+#endif
+
+    Sleep(10);
+
+    assert( 9 == client1->SendPacket(-1, test, 9));
+
+    // test start rec after a socket has revceived data
+    // result: packets received before first startReceive is saved by the OS
+/*
+    for(int i = 0; i < 100; i++)
+    {
+        assert( 9 == client1->SendPacket(-1, test, 9));
+    }
+    Sleep(10);
+    assert( 0 == client2->StartReceiving(20));
+
+//    assert( 0 == client2->StopReceiving());
+
+    Sleep(10);
+    for(int i = 0; i < 100; i++)
+    {
+        assert( 9 == client1->SendPacket(-1, test, 9));
+    }
+
+    assert( 0 == client2->StartReceiving(20));
+
+    for(int i = 0; i < 100; i++)
+    {
+        assert( 9 == client1->SendPacket(-1, test, 9));
+    }
+*/
+    Sleep(10);
+
+    assert( 0 == client1Callback->_counterRTP);
+    assert( 1 == client2Callback->_counterRTP);
+    assert( 0 == client1Callback->_counterRTCP);
+    assert( 0 == client2Callback->_counterRTCP);
+
+    printf("Sent 1 packet on one socket \n");
+
+    char ipAddr[64];
+    char tempIpAddr[64];
+    char ipMulticastAddr[64];
+    WebRtc_UWord16 rtpPort = 0;
+    WebRtc_UWord16 rtcpPort = 0;
+    bool reusableSocket = true;
+    assert( 0 == client2->RemoteSocketInformation(ipAddr, rtpPort, rtcpPort));
+    assert( rtpPort == 1234);
+    assert( strncmp(ipAddr, localIPAddr, 16) == 0);
+
+    assert( 0 == client2->ReceiveSocketInformation(ipAddr, rtpPort, rtcpPort, ipMulticastAddr, reusableSocket));
+    assert( rtpPort == 1236);
+    assert( rtcpPort == 1237);
+    assert( strncmp(ipAddr, "0.0.0.0", 16) == 0);
+    assert( ipMulticastAddr[0] == 0);
+    assert( reusableSocket == false);
+
+    assert( 0 == client2->SendSocketInformation(ipAddr, rtpPort, rtcpPort));
+    assert( rtpPort == 1234);
+    assert( rtcpPort == 1235);
+    assert( strncmp(ipAddr,localIPAddr, 16) == 0);
+
+    const int numberOfPackets = 1000;
+    int n = 0;
+    while(n < numberOfPackets)
+    {
+        assert( 9 == client1->SendPacket(-1, test, 9));
+        assert( 9 == client2->SendPacket(-1, test, 9));
+        assert( 9 == client1->SendRTCPPacket(-1, test, 9));
+        assert( 9 == client2->SendRTCPPacket(-1, test, 9));
+        n++;
+    }
+    int loops = 0;
+    for(; loops < 100 &&
+        !(client1Callback->_counterRTP == numberOfPackets &&
+        client1Callback->_counterRTCP == numberOfPackets &&
+        client2Callback->_counterRTP == numberOfPackets+1 &&
+        client2Callback->_counterRTCP == numberOfPackets);
+        loops++)
+    {
+        Sleep(10);
+    }
+    printf("\tSent %d packets on 4 sockets in:%d ms\n", numberOfPackets, loops*10);
+
+    assert( numberOfPackets == client1Callback->_counterRTP);
+    assert( numberOfPackets+1 == client2Callback->_counterRTP);
+    assert( numberOfPackets == client1Callback->_counterRTCP);
+    assert( numberOfPackets == client2Callback->_counterRTCP);
+
+    assert( 0 == client1->StopReceiving());
+    assert( 0 == client2->StopReceiving());
+
+    printf("Tear down client 2\n");
+
+    // configure that fail
+    assert( -1 == client2->InitializeReceiveSockets(client2Callback,1234, localIPAddr)); // port in use
+    assert( !client2->ReceiveSocketsInitialized());
+    assert( 0 == client2->InitializeReceiveSockets(client2Callback,1236));
+    assert( 0 == client2->StartReceiving(20));
+
+    printf("Client 2 re-configured\n");
+
+    assert( client1->SendSocketsInitialized());
+    assert( client1->ReceiveSocketsInitialized());
+    assert( client2->SendSocketsInitialized());
+    assert( client2->ReceiveSocketsInitialized());
+
+    assert( 9 == client1->SendPacket(-1, test, 9));
+
+    // this should not be received since we dont receive in client 1
+    assert( 9 == client2->SendPacket(-1, test, 9));
+
+    Sleep(10);
+
+    assert( numberOfPackets == client1Callback->_counterRTP);
+    assert( numberOfPackets+2 == client2Callback->_counterRTP);
+    assert( numberOfPackets == client1Callback->_counterRTCP);
+    assert( numberOfPackets == client2Callback->_counterRTCP);
+    printf("\tSent 1 packet on one socket \n");
+
+    printf("Start filter test\n");
+
+    assert( 0 == client1->StartReceiving(20));
+
+    assert( 0 == client1->SetFilterPorts(1234, 1235)); // should filter out what we send
+    assert( 0 == client1->SetFilterIP(localIPAddr));
+
+    assert( 0 == client1->FilterIP(tempIpAddr));
+    assert( strncmp(tempIpAddr, localIPAddr, 16) == 0);
+
+    assert( 9 == client2->SendPacket(-1, test, 9));
+    assert( 9 == client2->SendRTCPPacket(-1, test, 9));
+
+    Sleep(10);
+
+    assert( numberOfPackets == client1Callback->_counterRTP);
+    assert( numberOfPackets+2 == client2Callback->_counterRTP);
+    assert( numberOfPackets == client1Callback->_counterRTCP);
+    assert( numberOfPackets == client2Callback->_counterRTCP);
+
+    assert( 0 == client1->SetFilterPorts(1236, 1237)); // should pass through
+
+    assert( 9 == client2->SendPacket(-1, test, 9));
+    assert( 9 == client2->SendRTCPPacket(-1, test, 9));
+    printf("\tSent 1 packet on two sockets \n");
+
+    Sleep(10);
+
+    assert( numberOfPackets+1 == client1Callback->_counterRTP);
+    assert( numberOfPackets+2 == client2Callback->_counterRTP);
+    assert( numberOfPackets+1 == client1Callback->_counterRTCP);
+    assert( numberOfPackets == client2Callback->_counterRTCP);
+
+    assert( 0 == client1->SetFilterIP("127.0.0.2"));
+
+    assert( 9 == client2->SendPacket(-1, test, 9));
+    assert( 9 == client2->SendRTCPPacket(-1, test, 9));
+    printf("\tSent 1 packet on two sockets \n");
+
+    Sleep(10);
+
+    assert( numberOfPackets+1 == client1Callback->_counterRTP);
+    assert( numberOfPackets+2 == client2Callback->_counterRTP);
+    assert( numberOfPackets+1 == client1Callback->_counterRTCP);
+    assert( numberOfPackets == client2Callback->_counterRTCP);
+
+    assert( 0 == client1->SetFilterIP(NULL));
+    assert( 0 == client1->SetFilterPorts(0, 0));
+
+    printf("Tested filter \n");
+
+    assert( 0 == client2->InitializeSourcePorts(1238, 1239));
+    assert( 9 == client2->SendPacket(-1, test, 9));
+    assert( 9 == client2->SendRTCPPacket(-1, test, 9));
+    printf("\tSent 1 packet on two sockets \n");
+
+    Sleep(10);
+
+    assert( numberOfPackets+2 == client1Callback->_counterRTP);
+    assert( numberOfPackets+2 == client2Callback->_counterRTP);
+    assert( numberOfPackets+2 == client1Callback->_counterRTCP);
+    assert( numberOfPackets == client2Callback->_counterRTCP);
+
+    assert( 0 == client1->RemoteSocketInformation(ipAddr, rtpPort, rtcpPort));
+    assert( rtpPort == 1238);
+    assert( rtcpPort == 1239);
+    assert( strncmp(ipAddr, localIPAddr, 16) == 0);
+
+    printf("Tested source port \n");
+
+    assert( 0 == client2->InitializeSourcePorts(1240 ));
+    assert( 9 == client2->SendPacket(-1, test, 9));
+    assert( 9 == client2->SendRTCPPacket(-1, test, 9));
+    printf("\tSent 1 packet on two sockets \n");
+
+    Sleep(10);
+
+    assert( 0 == client1->RemoteSocketInformation(ipAddr, rtpPort, rtcpPort));
+    assert( rtpPort == 1240);
+    assert( rtcpPort == 1241);
+
+    printf("Tested SetSendPorts source port \n");
+
+    UdpTransport::Destroy(client1);
+    UdpTransport::Destroy(client2);
+
+    printf("\n\nUdpTransport test done\n");
+
+    delete client1Callback;
+    delete client2Callback;
+
+    Sleep(5000);
+    Trace::ReturnTrace();
+};
diff --git a/test/udp_transport.gyp b/test/udp_transport.gyp
deleted file mode 100644
index 37c9e73..0000000
--- a/test/udp_transport.gyp
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
-#
-# Use of this source code is governed by a BSD-style license
-# that can be found in the LICENSE file in the root of the source
-# tree. An additional intellectual property rights grant can be found
-# in the file PATENTS.  All contributing project authors may
-# be found in the AUTHORS file in the root of the source tree.
-
-{
-  'includes': [
-    '../build/common.gypi',
-  ],
-  'targets': [
-    {
-      'target_name': 'udp_transport',
-      'type': 'static_library',
-      'dependencies': [
-        '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
-      ],
-      'direct_dependent_settings': {
-        'include_dirs': [
-          'udp_transport/include',
-        ],
-      },
-      'sources': [
-        # PLATFORM INDEPENDENT SOURCE FILES
-        'udp_transport/channel_transport.cc',
-        'udp_transport/include/channel_transport.h',
-        'udp_transport/udp_transport.h',
-        'udp_transport/udp_transport_impl.cc',
-        'udp_transport/udp_socket_wrapper.cc',
-        'udp_transport/udp_socket_manager_wrapper.cc',
-        'udp_transport/udp_transport_impl.h',
-        'udp_transport/udp_socket_wrapper.h',
-        'udp_transport/udp_socket_manager_wrapper.h',
-        # PLATFORM SPECIFIC SOURCE FILES - Will be filtered below
-        # Posix (Linux/Mac)
-        'udp_transport/udp_socket_posix.cc',
-        'udp_transport/udp_socket_posix.h',
-        'udp_transport/udp_socket_manager_posix.cc',
-        'udp_transport/udp_socket_manager_posix.h',
-        # win
-        'udp_transport/udp_socket2_manager_win.cc',
-        'udp_transport/udp_socket2_manager_win.h',
-        'udp_transport/udp_socket2_win.cc',
-        'udp_transport/udp_socket2_win.h',
-        'udp_transport/traffic_control_win.cc',
-        'udp_transport/traffic_control_win.h',
-      ], # source
-    },
-    {
-      'target_name': 'udp_transport_unittests',
-      'type': 'executable',
-      'dependencies': [
-        'udp_transport',
-        '<(DEPTH)/testing/gtest.gyp:gtest',
-        '<(DEPTH)/testing/gmock.gyp:gmock',
-        '<(webrtc_root)/test/test.gyp:test_support_main',
-      ],
-      'sources': [
-        'udp_transport/udp_transport_unittest.cc',
-        'udp_transport/udp_socket_manager_unittest.cc',
-        'udp_transport/udp_socket_wrapper_unittest.cc',
-      ],
-      # Disable warnings to enable Win64 build, issue 1323.
-      'msvs_disabled_warnings': [
-        4267,  # size_t to int truncation.
-      ],
-    }, # udp_transport_unittests
-  ], # targets
-}
diff --git a/test/udp_transport/channel_transport.cc b/test/udp_transport/channel_transport.cc
deleted file mode 100644
index 8be8938..0000000
--- a/test/udp_transport/channel_transport.cc
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-
-#include "webrtc/test/udp_transport/udp_transport.h"
-#include "webrtc/video_engine/include/vie_network.h"
-#include "webrtc/voice_engine/include/voe_network.h"
-
-namespace webrtc {
-
-VoiceChannelTransport::VoiceChannelTransport(VoENetwork* voe_network,
-                                             int channel)
-    : channel_(channel),
-      voe_network_(voe_network) {
-  WebRtc_UWord8 socket_threads = 1;
-  socket_transport_ = UdpTransport::Create(channel, socket_threads);
-  voe_network_->RegisterExternalTransport(channel, *socket_transport_);
-}
-
-VoiceChannelTransport::~VoiceChannelTransport() {
-  voe_network_->DeRegisterExternalTransport(channel_);
-  UdpTransport::Destroy(socket_transport_);
-}
-
-void VoiceChannelTransport::IncomingRTPPacket(
-    const WebRtc_Word8* incoming_rtp_packet,
-    const WebRtc_Word32 packet_length,
-    const char* /*from_ip*/,
-    const WebRtc_UWord16 /*from_port*/) {
-  voe_network_->ReceivedRTPPacket(channel_, incoming_rtp_packet, packet_length);
-}
-
-void VoiceChannelTransport::IncomingRTCPPacket(
-    const WebRtc_Word8* incoming_rtcp_packet,
-    const WebRtc_Word32 packet_length,
-    const char* /*from_ip*/,
-    const WebRtc_UWord16 /*from_port*/) {
-  voe_network_->ReceivedRTCPPacket(channel_, incoming_rtcp_packet,
-                                   packet_length);
-}
-
-int VoiceChannelTransport::SetLocalReceiver(WebRtc_UWord16 rtp_port) {
-  return socket_transport_->InitializeReceiveSockets(this, rtp_port);
-}
-
-int VoiceChannelTransport::SetSendDestination(const char* ip_address,
-                                              WebRtc_UWord16 rtp_port) {
-  return socket_transport_->InitializeSendSockets(ip_address, rtp_port);
-}
-
-
-VideoChannelTransport::VideoChannelTransport(ViENetwork* vie_network,
-                                             int channel)
-    : channel_(channel),
-      vie_network_(vie_network) {
-  WebRtc_UWord8 socket_threads = 1;
-  socket_transport_ = UdpTransport::Create(channel, socket_threads);
-  vie_network_->RegisterSendTransport(channel, *socket_transport_);
-}
-  
-VideoChannelTransport::~VideoChannelTransport() {
-  vie_network_->DeregisterSendTransport(channel_);
-  UdpTransport::Destroy(socket_transport_);
-}
-
-void VideoChannelTransport::IncomingRTPPacket(
-    const WebRtc_Word8* incoming_rtp_packet,
-    const WebRtc_Word32 packet_length,
-    const char* /*from_ip*/,
-    const WebRtc_UWord16 /*from_port*/) {
-  vie_network_->ReceivedRTPPacket(channel_, incoming_rtp_packet, packet_length);
-}
-
-void VideoChannelTransport::IncomingRTCPPacket(
-    const WebRtc_Word8* incoming_rtcp_packet,
-    const WebRtc_Word32 packet_length,
-    const char* /*from_ip*/,
-    const WebRtc_UWord16 /*from_port*/) {
-  vie_network_->ReceivedRTCPPacket(channel_, incoming_rtcp_packet,
-                                   packet_length);
-}
-
-int VideoChannelTransport::SetLocalReceiver(WebRtc_UWord16 rtp_port) {
-  return socket_transport_->InitializeReceiveSockets(this, rtp_port);
-}
-
-int VideoChannelTransport::SetSendDestination(const char* ip_address,
-                                              WebRtc_UWord16 rtp_port) {
-  return socket_transport_->InitializeSendSockets(ip_address, rtp_port);
-}
-
-} // namespace webrtc
diff --git a/test/udp_transport/include/channel_transport.h b/test/udp_transport/include/channel_transport.h
deleted file mode 100644
index e3291ef..0000000
--- a/test/udp_transport/include/channel_transport.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
- *
- *  Use of this source code is governed by a BSD-style license
- *  that can be found in the LICENSE file in the root of the source
- *  tree. An additional intellectual property rights grant can be found
- *  in the file PATENTS.  All contributing project authors may
- *  be found in the AUTHORS file in the root of the source tree.
- */
-
-#ifndef WEBRTC_TEST_UDP_TRANSPORT_INTERFACE_CHANNEL_TRANSPORT_H_
-#define WEBRTC_TEST_UDP_TRANSPORT_INTERFACE_CHANNEL_TRANSPORT_H_
-
-#include "webrtc/test/udp_transport/udp_transport.h"
-
-namespace webrtc {
-
-class ViENetwork;
-class VoENetwork;
-
-// Helper class for VoiceEngine tests.
-class VoiceChannelTransport : public UdpTransportData {
- public:
-  VoiceChannelTransport(VoENetwork* voe_network, int channel);
-
-  virtual ~VoiceChannelTransport();
-
-  // Start implementation of UdpTransportData.
-  void IncomingRTPPacket(const WebRtc_Word8* incoming_rtp_packet,
-                         const WebRtc_Word32 packet_length,
-                         const char* /*from_ip*/,
-                         const WebRtc_UWord16 /*from_port*/);
-
-  void IncomingRTCPPacket(const WebRtc_Word8* incoming_rtcp_packet,
-                          const WebRtc_Word32 packet_length,
-                          const char* /*from_ip*/,
-                          const WebRtc_UWord16 /*from_port*/);
-  // End implementation of UdpTransportData.
-
-  // Specifies the ports to receive RTP packets on.
-  int SetLocalReceiver(WebRtc_UWord16 rtp_port);
-
-  // Specifies the destination port and IP address for a specified channel.  
-  int SetSendDestination(const char* ip_address, WebRtc_UWord16 rtp_port);
-
- private:
-  int channel_;
-  VoENetwork* voe_network_;
-  UdpTransport* socket_transport_;
-};
-
-// Helper class for VideoEngine tests.
-class VideoChannelTransport : public UdpTransportData {
- public:
-  VideoChannelTransport(ViENetwork* vie_network, int channel);
-
-  virtual  ~VideoChannelTransport();
-
-  // Start implementation of UdpTransportData.
-  void IncomingRTPPacket(const WebRtc_Word8* incoming_rtp_packet,
-                         const WebRtc_Word32 packet_length,
-                         const char* /*from_ip*/,
-                         const WebRtc_UWord16 /*from_port*/);
-
-  void IncomingRTCPPacket(const WebRtc_Word8* incoming_rtcp_packet,
-                          const WebRtc_Word32 packet_length,
-                          const char* /*from_ip*/,
-                          const WebRtc_UWord16 /*from_port*/);
-  // End implementation of UdpTransportData.
-
-  // Specifies the ports to receive RTP packets on.
-  int SetLocalReceiver(WebRtc_UWord16 rtp_port);
-
-  // Specifies the destination port and IP address for a specified channel.  
-  int SetSendDestination(const char* ip_address, WebRtc_UWord16 rtp_port);
-
- private:
-  int channel_;
-  ViENetwork* vie_network_;
-  UdpTransport* socket_transport_;
-};
-
-} // namespace webrtc
-
-#endif // WEBRTC_TEST_UDP_TRANSPORT_INTERFACE_CHANNEL_TRANSPORT_H_
-
diff --git a/video_engine/include/vie_network.h b/video_engine/include/vie_network.h
index d3515db..9752008 100644
--- a/video_engine/include/vie_network.h
+++ b/video_engine/include/vie_network.h
@@ -65,6 +65,34 @@
   // for all sub-API:s before the VideoEngine object can be safely deleted.
   virtual int Release() = 0;
 
+  // Specifies the ports to receive RTP packets on. It is also possible to set
+  // port for RTCP and local IP address.
+  virtual int SetLocalReceiver(const int video_channel,
+                               const unsigned short rtp_port,
+                               const unsigned short rtcp_port = 0,
+                               const char* ip_address = NULL) = 0;
+
+  // Gets the local receiver ports and address for a specified channel.
+  virtual int GetLocalReceiver(const int video_channel,
+                               unsigned short& rtp_port,
+                               unsigned short& rtcp_port, char* ip_address) = 0;
+
+  // Specifies the destination port and IP address for a specified channel.
+  virtual int SetSendDestination(const int video_channel,
+                                 const char* ip_address,
+                                 const unsigned short rtp_port,
+                                 const unsigned short rtcp_port = 0,
+                                 const unsigned short source_rtp_port = 0,
+                                 const unsigned short source_rtcp_port = 0) = 0;
+
+  // Get the destination port and address for a specified channel.
+  virtual int GetSendDestination(const int video_channel,
+                                 char* ip_address,
+                                 unsigned short& rtp_port,
+                                 unsigned short& rtcp_port,
+                                 unsigned short& source_rtp_port,
+                                 unsigned short& source_rtcp_port) = 0;
+
   // This function registers a user implementation of Transport to use for
   // sending RTP and RTCP packets on this channel.
   virtual int RegisterSendTransport(const int video_channel,
@@ -86,6 +114,63 @@
                                  const void* data,
                                  const int length) = 0;
 
+  // Gets the source ports and IP address of the incoming stream for a
+  // specified channel.
+  virtual int GetSourceInfo(const int video_channel,
+                            unsigned short& rtp_port,
+                            unsigned short& rtcp_port,
+                            char* ip_address,
+                            unsigned int ip_address_length) = 0;
+
+  // Gets the local IP address, in string format.
+  virtual int GetLocalIP(char ip_address[64], bool ipv6 = false) = 0;
+
+  // Enables IPv6, instead of IPv4, for a specified channel.
+  virtual int EnableIPv6(int video_channel) = 0;
+
+  // The function returns true if IPv6 is enabled, false otherwise.
+  virtual bool IsIPv6Enabled(int video_channel) = 0;
+
+  // Enables a port and IP address filtering for incoming packets on a
+  // specific channel.
+  virtual int SetSourceFilter(const int video_channel,
+                              const unsigned short rtp_port,
+                              const unsigned short rtcp_port = 0,
+                              const char* ip_address = NULL) = 0;
+
+  // Gets current port and IP address filter for a specified channel.
+  virtual int GetSourceFilter(const int video_channel,
+                              unsigned short& rtp_port,
+                              unsigned short& rtcp_port,
+                              char* ip_address) = 0;
+
+  // This function sets the six‐bit Differentiated Services Code Point (DSCP)
+  // in the IP header of the outgoing stream for a specific channel.
+  // Windows and Linux only.
+  virtual int SetSendToS(const int video_channel,
+                         const int DSCP,
+                         const bool use_set_sockOpt = false) = 0;
+
+  // Retrieves the six‐bit Differentiated Services Code Point (DSCP) in the IP
+  // header of the outgoing stream for a specific channel.
+  virtual int GetSendToS(const int video_channel,
+                         int& DSCP,
+                         bool& use_set_sockOpt) = 0;
+
+  // This function sets the Generic Quality of Service (GQoS) service level.
+  // The Windows operating system then maps to a Differentiated Services Code
+  // Point (DSCP) and to an 802.1p setting. Windows only.
+  virtual int SetSendGQoS(const int video_channel, const bool enable,
+                          const int service_type,
+                          const int overrideDSCP = 0) = 0;
+
+  // This function retrieves the currently set GQoS service level for a
+  // specific channel.
+  virtual int GetSendGQoS(const int video_channel,
+                          bool& enabled,
+                          int& service_type,
+                          int& overrideDSCP) = 0;
+
   // This function sets the Maximum Transition Unit (MTU) for a channel. The
   // RTP packet will be packetized based on this MTU to optimize performance
   // over the network.
@@ -112,6 +197,14 @@
       const bool enable,
       const unsigned int sample_time_seconds = KDefaultSampleTimeSeconds) = 0;
 
+  // This function handles sending a raw UDP data packet over an existing RTP
+  // or RTCP socket.
+  virtual int SendUDPPacket(const int video_channel,
+                            const void* data,
+                            const unsigned int length,
+                            int& transmitted_bytes,
+                            bool use_rtcp_socket = false) = 0;
+
  protected:
   ViENetwork() {}
   virtual ~ViENetwork() {}
diff --git a/video_engine/test/android/jni/vie_android_java_api.cc b/video_engine/test/android/jni/vie_android_java_api.cc
index d1b6f2b..8c8aa0b 100644
--- a/video_engine/test/android/jni/vie_android_java_api.cc
+++ b/video_engine/test/android/jni/vie_android_java_api.cc
@@ -34,9 +34,6 @@
 #include "common_types.h"
 #include "android_media_codec_decoder.h"
 
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-
 #define WEBRTC_LOG_TAG "*WEBRTCN*"
 #define VALIDATE_BASE_POINTER                                           \
   if (!voeData.base)                                                    \
@@ -110,8 +107,6 @@
   VoEHardware* hardware;
   VoERTP_RTCP* rtp;
   JavaVM* jvm;
-  scoped_ptr<VoiceChannelTransport> transport;
-  // TODO
 } VoiceEngineData;
 
 class AndroidVideoRenderCallback;
@@ -127,7 +122,6 @@
   ViECapture* capture;
   ViEExternalCodec* externalCodec;
   VideoCallbackAndroid* callback;
-  scoped_ptr<VideoChannelTransport> transport;
 
 } VideoEngineData;
 
@@ -595,7 +589,7 @@
     if (voiceChannel >= 0) {
       vieData.base->ConnectAudioChannel(channel, voiceChannel);
     }
-    vieData.transport.reset(new VideoChannelTransport(vieData.netw, channel));
+
     return channel;
   }
   else {
@@ -616,10 +610,13 @@
 {
   __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetLocalReceiver");
 
-  if (vieData.transport.get()) {
-    return vieData.transport->SetLocalReceiver(port);
+  if (vieData.vie) {
+    int ret = vieData.netw->SetLocalReceiver(channel, port);
+    return ret;
   }
-  return -1;
+  else {
+    return -1;
+  }
 }
 
 /*
@@ -649,10 +646,7 @@
                       "SetSendDestination: channel=%d, port=%d, ip=%s\n",
                       channel, port, ip);
 
-  if (vieData.transport.get()) {
-    return vieData.transport->SetSendDestination(ip, port);
-  }
-  return -1;
+  return vieData.netw->SetSendDestination(channel, ip, port);
 }
 
 
@@ -1270,7 +1264,7 @@
   }
 
   jint channel = voeData.base->CreateChannel();
-  voeData.transport.reset(new VoiceChannelTransport(voeData.netw, channel));
+
   return channel;
 }
 
@@ -1301,10 +1295,7 @@
 {
   __android_log_write(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG, "SetLocalReceiver");
   VALIDATE_BASE_POINTER;
-  if (voeData.transport.get()) {
-    return voeData.transport->SetLocalReceiver(port);
-  }
-  return -1;
+  return voeData.base->SetLocalReceiver(channel, port);
 }
 
 /*
@@ -1328,13 +1319,9 @@
                         "Could not get UTF string");
     return -1;
   }
-  if (voeData.transport.get()) {
-    jint retVal = voeData.transport->SetSendDestination(ipaddrNative, port);
-    env->ReleaseStringUTFChars(ipaddr, ipaddrNative);
-    return retVal;
-  }
+  jint retVal = voeData.base->SetSendDestination(channel, port, ipaddrNative);
   env->ReleaseStringUTFChars(ipaddr, ipaddrNative);
-  return -1;
+  return retVal;
 }
 
 /*
diff --git a/video_engine/test/auto_test/automated/vie_api_integration_test.cc b/video_engine/test/auto_test/automated/vie_api_integration_test.cc
index 96b401b..7b49103 100644
--- a/video_engine/test/auto_test/automated/vie_api_integration_test.cc
+++ b/video_engine/test/auto_test/automated/vie_api_integration_test.cc
@@ -48,6 +48,10 @@
   tests_->ViEImageProcessAPITest();
 }
 
+TEST_F(DISABLED_ON_MAC(ViEApiIntegrationTest), RunsNetworkTestWithoutErrors) {
+  tests_->ViENetworkAPITest();
+}
+
 TEST_F(DISABLED_ON_MAC(ViEApiIntegrationTest), RunsRenderTestWithoutErrors) {
   tests_->ViERenderAPITest();
 }
diff --git a/video_engine/test/auto_test/automated/vie_extended_integration_test.cc b/video_engine/test/auto_test/automated/vie_extended_integration_test.cc
index d224bde..c091475 100644
--- a/video_engine/test/auto_test/automated/vie_extended_integration_test.cc
+++ b/video_engine/test/auto_test/automated/vie_extended_integration_test.cc
@@ -51,6 +51,11 @@
 }
 
 TEST_F(DISABLED_ON_MAC(ViEExtendedIntegrationTest),
+       RunsNetworkTestWithoutErrors) {
+  tests_->ViENetworkExtendedTest();
+}
+
+TEST_F(DISABLED_ON_MAC(ViEExtendedIntegrationTest),
        RunsRenderTestWithoutErrors) {
   tests_->ViERenderExtendedTest();
 }
diff --git a/video_engine/test/auto_test/automated/vie_standard_integration_test.cc b/video_engine/test/auto_test/automated/vie_standard_integration_test.cc
index 30364e0..4f90aac 100644
--- a/video_engine/test/auto_test/automated/vie_standard_integration_test.cc
+++ b/video_engine/test/auto_test/automated/vie_standard_integration_test.cc
@@ -54,6 +54,10 @@
   tests_->ViEImageProcessStandardTest();
 }
 
+TEST_F(ViEStandardIntegrationTest, RunsNetworkTestWithoutErrors)  {
+  tests_->ViENetworkStandardTest();
+}
+
 TEST_F(ViEStandardIntegrationTest, RunsRenderTestWithoutErrors)  {
   tests_->ViERenderStandardTest();
 }
diff --git a/video_engine/test/auto_test/source/vie_autotest.cc b/video_engine/test/auto_test/source/vie_autotest.cc
index 200e256..363eccb 100644
--- a/video_engine/test/auto_test/source/vie_autotest.cc
+++ b/video_engine/test/auto_test/source/vie_autotest.cc
@@ -67,6 +67,7 @@
     ViEEncryptionStandardTest();
     ViEFileStandardTest();
     ViEImageProcessStandardTest();
+    ViENetworkStandardTest();
     ViERenderStandardTest();
     ViERtpRtcpStandardTest();
 }
@@ -79,6 +80,7 @@
     ViEEncryptionExtendedTest();
     ViEFileExtendedTest();
     ViEImageProcessExtendedTest();
+    ViENetworkExtendedTest();
     ViERenderExtendedTest();
     ViERtpRtcpExtendedTest();
 }
@@ -91,6 +93,7 @@
     ViEEncryptionAPITest();
     ViEFileAPITest();
     ViEImageProcessAPITest();
+    ViENetworkAPITest();
     ViERenderAPITest();
     ViERtpRtcpAPITest();
 }
diff --git a/video_engine/test/auto_test/source/vie_autotest_android.cc b/video_engine/test/auto_test/source/vie_autotest_android.cc
index 80d8d90..d1622db 100644
--- a/video_engine/test/auto_test/source/vie_autotest_android.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_android.cc
@@ -162,14 +162,21 @@
           vieAutoTest.ViEImageProcessExtendedTest();
           break;
 
-        case 8: // Render
+        case 8: // network
+          vieAutoTest.ViENetworkExtendedTest();
+          break;
+
+        case 9: // Render
           vieAutoTest.ViERenderExtendedTest();
           break;
 
-        case 9: // RTP/RTCP
+        case 10: // RTP/RTCP
           vieAutoTest.ViERtpRtcpExtendedTest();
           break;
 
+        case 11:
+          break;
+
         default:
           break;
       }
diff --git a/video_engine/test/auto_test/source/vie_autotest_base.cc b/video_engine/test/auto_test/source/vie_autotest_base.cc
index 05572ea..e9d24f3 100644
--- a/video_engine/test/auto_test/source/vie_autotest_base.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_base.cc
@@ -9,12 +9,11 @@
  */
 
 #include "webrtc/modules/video_capture/include/video_capture_factory.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-#include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
-#include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h"
-#include "webrtc/video_engine/test/auto_test/primitives/base_primitives.h"
-#include "webrtc/video_engine/test/auto_test/primitives/general_primitives.h"
-#include "webrtc/video_engine/test/libvietest/include/tb_interfaces.h"
+#include "video_engine/test/auto_test/interface/vie_autotest.h"
+#include "video_engine/test/auto_test/interface/vie_autotest_defines.h"
+#include "video_engine/test/auto_test/primitives/base_primitives.h"
+#include "video_engine/test/auto_test/primitives/general_primitives.h"
+#include "video_engine/test/libvietest/include/tb_interfaces.h"
 
 void ViEAutoTest::ViEBaseStandardTest() {
   // ***************************************************************
@@ -151,30 +150,20 @@
   // Create a receive only channel and a send channel. Verify we can't send on
   // the receive only channel.
   EXPECT_EQ(0, vie_base->CreateReceiveChannel(video_channel2,
-                                              video_channel));
+                                                  video_channel));
   EXPECT_EQ(0, vie_base->CreateChannel(video_channel3, video_channel));
 
   const char* ip_address = "127.0.0.1\0";
   const int send_port = 1234;
-
   EXPECT_EQ(0, vie_rtp->SetLocalSSRC(video_channel, 1));
+  EXPECT_EQ(0, vie_network->SetSendDestination(video_channel, ip_address,
+                                               send_port));
   EXPECT_EQ(0, vie_rtp->SetLocalSSRC(video_channel, 2));
+  EXPECT_EQ(0, vie_network->SetSendDestination(video_channel2, ip_address,
+                                               send_port + 2));
   EXPECT_EQ(0, vie_rtp->SetLocalSSRC(video_channel, 3));
-  
-  webrtc::VideoChannelTransport* video_channel_transport_1 =
-      new webrtc::VideoChannelTransport(vie_network, video_channel);
-
-  ASSERT_EQ(0, video_channel_transport_1->SetSendDestination(ip_address,
-                                                             send_port));
-
-  webrtc::VideoChannelTransport* video_channel_transport_2 =
-      new webrtc::VideoChannelTransport(vie_network, video_channel2);
-
-  webrtc::VideoChannelTransport* video_channel_transport_3 =
-      new webrtc::VideoChannelTransport(vie_network, video_channel3);
-
-  ASSERT_EQ(0, video_channel_transport_3->SetSendDestination(ip_address,
-                                                             send_port + 4));
+  EXPECT_EQ(0, vie_network->SetSendDestination(video_channel3, ip_address,
+                                               send_port + 4));
 
   EXPECT_EQ(0, vie_base->StartSend(video_channel));
   EXPECT_EQ(-1, vie_base->StartSend(video_channel2));
@@ -231,9 +220,6 @@
   EXPECT_FALSE(webrtc::VideoEngine::Delete(video_engine)) <<
       "Should fail since there are interfaces left.";
 
-  delete video_channel_transport_1;
-  delete video_channel_transport_2;
-  delete video_channel_transport_3;
   EXPECT_EQ(0, vie_base->Release());
   EXPECT_TRUE(webrtc::VideoEngine::Delete(video_engine));
 }
diff --git a/video_engine/test/auto_test/source/vie_autotest_codec.cc b/video_engine/test/auto_test/source/vie_autotest_codec.cc
index 74ce9d0..87169a6 100644
--- a/video_engine/test/auto_test/source/vie_autotest_codec.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_codec.cc
@@ -8,24 +8,21 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "webrtc/common_types.h"
-#include "webrtc/engine_configurations.h"
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-#include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h"
-#include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
-#include "webrtc/video_engine/test/libvietest/include/tb_capture_device.h"
-#include "webrtc/video_engine/test/libvietest/include/tb_I420_codec.h"
-#include "webrtc/video_engine/test/libvietest/include/tb_interfaces.h"
-#include "webrtc/video_engine/test/libvietest/include/tb_video_channel.h"
-#include "webrtc/video_engine/include/vie_base.h"
-#include "webrtc/video_engine/include/vie_capture.h"
-#include "webrtc/video_engine/include/vie_codec.h"
-#include "webrtc/video_engine/include/vie_external_codec.h"
-#include "webrtc/video_engine/include/vie_network.h"
-#include "webrtc/video_engine/include/vie_render.h"
-#include "webrtc/video_engine/include/vie_rtp_rtcp.h"
-#include "webrtc/voice_engine/include/voe_base.h"
+#include "common_types.h"  // NOLINT
+#include "engine_configurations.h"  // NOLINT
+#include "video_engine/test/auto_test/interface/vie_autotest_defines.h"
+#include "video_engine/test/auto_test/interface/vie_autotest.h"
+#include "video_engine/test/libvietest/include/tb_capture_device.h"
+#include "video_engine/test/libvietest/include/tb_I420_codec.h"
+#include "video_engine/test/libvietest/include/tb_interfaces.h"
+#include "video_engine/test/libvietest/include/tb_video_channel.h"
+#include "video_engine/include/vie_base.h"
+#include "video_engine/include/vie_capture.h"
+#include "video_engine/include/vie_codec.h"
+#include "video_engine/include/vie_network.h"
+#include "video_engine/include/vie_render.h"
+#include "video_engine/include/vie_rtp_rtcp.h"
+#include "voice_engine/include/voe_base.h"
 
 class TestCodecObserver
     : public webrtc::ViEEncoderObserver,
@@ -167,16 +164,13 @@
       break;
     }
   }
+
   const char* ip_address = "127.0.0.1";
   const uint16_t rtp_port = 6000;
-
-  webrtc::scoped_ptr<webrtc::VideoChannelTransport> video_channel_transport(
-      new webrtc::VideoChannelTransport(network, video_channel));
-
-  ASSERT_EQ(0, video_channel_transport->SetSendDestination(ip_address,
-                                                           rtp_port));
-  ASSERT_EQ(0, video_channel_transport->SetLocalReceiver(rtp_port));
-
+  EXPECT_EQ(0, network->SetLocalReceiver(video_channel, rtp_port));
+  EXPECT_EQ(0, base->StartReceive(video_channel));
+  EXPECT_EQ(0, network->SetSendDestination(
+      video_channel, ip_address, rtp_port));
   EXPECT_EQ(0, base->StartSend(video_channel));
 
   // Make sure all codecs runs
@@ -306,14 +300,10 @@
 
     const char* ip_address = "127.0.0.1";
     const uint16_t rtp_port = 6000;
-    
-    webrtc::scoped_ptr<webrtc::VideoChannelTransport> video_channel_transport(
-        new webrtc::VideoChannelTransport(network, video_channel));
-
-    ASSERT_EQ(0, video_channel_transport->SetSendDestination(ip_address,
-                                                             rtp_port));
-    ASSERT_EQ(0, video_channel_transport->SetLocalReceiver(rtp_port));
-    
+    EXPECT_EQ(0, network->SetLocalReceiver(video_channel, rtp_port));
+    EXPECT_EQ(0, base->StartReceive(video_channel));
+    EXPECT_EQ(0, network->SetSendDestination(
+        video_channel, ip_address, rtp_port));
     EXPECT_EQ(0, base->StartSend(video_channel));
 
     // Codec specific tests
@@ -339,7 +329,6 @@
     // the received streams.
     TbInterfaces video_engine("ViECodecExtendedTest2");
     TbCaptureDevice tb_capture(video_engine);
-    webrtc::ViENetwork* network = video_engine.network;
 
     // Create channel 1.
     int video_channel_1 = -1;
@@ -352,25 +341,17 @@
     EXPECT_NE(video_channel_1, video_channel_2)
         << "Channel 2 should be unique.";
 
-    const char* ip_address = "127.0.0.1";
     uint16_t rtp_port_1 = 12000;
     uint16_t rtp_port_2 = 13000;
-    
-    webrtc::scoped_ptr<webrtc::VideoChannelTransport> video_channel_transport_1(
-        new webrtc::VideoChannelTransport(network, video_channel_1));
-
-    ASSERT_EQ(0, video_channel_transport_1->SetSendDestination(ip_address,
-                                                               rtp_port_1));
-    ASSERT_EQ(0, video_channel_transport_1->SetLocalReceiver(rtp_port_1));
-
-    webrtc::scoped_ptr<webrtc::VideoChannelTransport> video_channel_transport_2(
-        new webrtc::VideoChannelTransport(network, video_channel_2));
-
-    ASSERT_EQ(0, video_channel_transport_2->SetSendDestination(ip_address,
-                                                               rtp_port_2));
-    ASSERT_EQ(0, video_channel_transport_2->SetLocalReceiver(rtp_port_2));
-
+    EXPECT_EQ(0, video_engine.network->SetLocalReceiver(
+        video_channel_1, rtp_port_1));
+    EXPECT_EQ(0, video_engine.network->SetSendDestination(
+        video_channel_1, "127.0.0.1", rtp_port_1));
     EXPECT_EQ(0, video_engine.rtp_rtcp->SetLocalSSRC(video_channel_1, 1));
+    EXPECT_EQ(0, video_engine.network->SetLocalReceiver(
+        video_channel_2, rtp_port_2));
+    EXPECT_EQ(0, video_engine.network->SetSendDestination(
+        video_channel_2, "127.0.0.1", rtp_port_2));
     EXPECT_EQ(0, video_engine.rtp_rtcp->SetLocalSSRC(video_channel_2, 2));
     tb_capture.ConnectTo(video_channel_1);
     tb_capture.ConnectTo(video_channel_2);
@@ -502,6 +483,9 @@
   EXPECT_TRUE(webrtc::VideoEngine::Delete(video_engine));
 }
 
+#ifdef WEBRTC_VIDEO_ENGINE_EXTERNAL_CODEC_API
+#include "video_engine/include/vie_external_codec.h"
+#endif
 void ViEAutoTest::ViECodecExternalCodecTest() {
   ViETest::Log(" ");
   ViETest::Log("========================================");
diff --git a/video_engine/test/auto_test/source/vie_autotest_custom_call.cc b/video_engine/test/auto_test/source/vie_autotest_custom_call.cc
index 8c03d07..b862b64 100644
--- a/video_engine/test/auto_test/source/vie_autotest_custom_call.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_custom_call.cc
@@ -15,15 +15,12 @@
 #include <algorithm>
 
 #include "gflags/gflags.h"
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-#include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
-#include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h"
-#include "webrtc/video_engine/test/auto_test/primitives/choice_helpers.h"
-#include "webrtc/video_engine/test/auto_test/primitives/general_primitives.h"
-#include "webrtc/video_engine/test/auto_test/primitives/input_helpers.h"
-#include "webrtc/video_engine/test/libvietest/include/vie_to_file_renderer.h"
-#include "webrtc/voice_engine/include/voe_network.h"
+#include "video_engine/test/auto_test/interface/vie_autotest.h"
+#include "video_engine/test/auto_test/interface/vie_autotest_defines.h"
+#include "video_engine/test/auto_test/primitives/choice_helpers.h"
+#include "video_engine/test/auto_test/primitives/general_primitives.h"
+#include "video_engine/test/auto_test/primitives/input_helpers.h"
+#include "video_engine/test/libvietest/include/vie_to_file_renderer.h"
 
 #define VCM_RED_PAYLOAD_TYPE                            96
 #define VCM_ULPFEC_PAYLOAD_TYPE                         97
@@ -205,12 +202,6 @@
                                          "ERROR: %s at line %d", __FUNCTION__,
                                          __LINE__);
 
-  webrtc::VoENetwork* voe_network=
-      webrtc::VoENetwork::GetInterface(voe);
-  number_of_errors += ViETest::TestError(voe_network != NULL,
-                                         "ERROR: %s at line %d", __FUNCTION__,
-                                         __LINE__);
-
   webrtc::VoEAudioProcessing* voe_apm =
       webrtc::VoEAudioProcessing::GetInterface(voe);
   number_of_errors += ViETest::TestError(voe_apm != NULL,
@@ -279,8 +270,6 @@
   int buffer_delay_ms = 0;
   bool is_image_scale_enabled = false;
   bool remb = true;
-  webrtc::scoped_ptr<webrtc::VideoChannelTransport> video_channel_transport;
-  webrtc::scoped_ptr<webrtc::VoiceChannelTransport> voice_channel_transport;
 
   while (!start_call) {
     // Get the IP address to use from call.
@@ -351,17 +340,13 @@
   if (start_call == true) {
     // Configure audio channel first.
     audio_channel = voe_base->CreateChannel();
-
-    voice_channel_transport.reset(
-        new webrtc::VoiceChannelTransport(voe_network, audio_channel));
-
-    error = voice_channel_transport->SetSendDestination(ip_address.c_str(),
-                                                        audio_tx_port);
+    error = voe_base->SetSendDestination(audio_channel, audio_tx_port,
+                                         ip_address.c_str());
     number_of_errors += ViETest::TestError(error == 0,
                                            "ERROR: %s at line %d",
                                            __FUNCTION__, __LINE__);
 
-    error = voice_channel_transport->SetLocalReceiver(audio_rx_port);
+    error = voe_base->SetLocalReceiver(audio_channel, audio_rx_port);
     number_of_errors += ViETest::TestError(error == 0,
                                            "ERROR: %s at line %d",
                                            __FUNCTION__, __LINE__);
@@ -487,17 +472,13 @@
       file_renderer.PrepareForRendering(output_path, filename);
       RenderToFile(vie_renderer, video_channel, &file_renderer);
     }
-    
-    video_channel_transport.reset(
-        new webrtc::VideoChannelTransport(vie_network, video_channel));
-
-    error = video_channel_transport->SetSendDestination(ip_address.c_str(),
-                                                        video_tx_port);
+    error = vie_network->SetSendDestination(video_channel, ip_address.c_str(),
+                                                video_tx_port);
     number_of_errors += ViETest::TestError(error == 0,
                                            "ERROR: %s at line %d",
                                            __FUNCTION__, __LINE__);
 
-    error = video_channel_transport->SetLocalReceiver(video_rx_port);
+    error = vie_network->SetLocalReceiver(video_channel, video_rx_port);
     number_of_errors += ViETest::TestError(error == 0,
                                            "ERROR: %s at line %d",
                                            __FUNCTION__, __LINE__);
@@ -931,9 +912,6 @@
     // Now tear down the ViE engine.
     error = vie_base->DisconnectAudioChannel(video_channel);
 
-    voice_channel_transport.reset(NULL);
-    video_channel_transport.reset(NULL);
-
     // If Encoder/Decoder Observer is running, delete them.
     if (codec_encoder_observer) {
       error = vie_codec->DeregisterEncoderObserver(video_channel);
diff --git a/video_engine/test/auto_test/source/vie_autotest_file.cc b/video_engine/test/auto_test/source/vie_autotest_file.cc
index ce2d327..8083171 100644
--- a/video_engine/test/auto_test/source/vie_autotest_file.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_file.cc
@@ -18,9 +18,6 @@
 
 #include "voe_codec.h"
 
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-
 class ViEAutotestFileObserver: public webrtc::ViEFileObserver
 {
 public:
@@ -106,18 +103,14 @@
                 break;
             }
         }
+
+
         const char* ipAddress = "127.0.0.1";
         const unsigned short rtpPort = 6000;
-
-        webrtc::scoped_ptr<webrtc::VideoChannelTransport>
-            video_channel_transport(
-                new webrtc::VideoChannelTransport(ptrViENetwork, videoChannel));
-
-        EXPECT_EQ(0, video_channel_transport->SetSendDestination(ipAddress,
-                                                                 rtpPort));
-        EXPECT_EQ(0, video_channel_transport->SetLocalReceiver(rtpPort));
-
+        EXPECT_EQ(0, ptrViENetwork->SetLocalReceiver(videoChannel, rtpPort));
         EXPECT_EQ(0, ptrViEBase->StartReceive(videoChannel));
+        EXPECT_EQ(0, ptrViENetwork->SetSendDestination(
+            videoChannel, ipAddress, rtpPort));
         EXPECT_EQ(0, ptrViEBase->StartSend(videoChannel));
         webrtc::ViEFile* ptrViEFile = webrtc::ViEFile::GetInterface(ptrViE);
         EXPECT_TRUE(ptrViEFile != NULL);
diff --git a/video_engine/test/auto_test/source/vie_autotest_loopback.cc b/video_engine/test/auto_test/source/vie_autotest_loopback.cc
index 8799418..1f8fcdd 100644
--- a/video_engine/test/auto_test/source/vie_autotest_loopback.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_loopback.cc
@@ -32,8 +32,6 @@
 #include "vie_network.h"
 #include "vie_render.h"
 #include "vie_rtp_rtcp.h"
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
 
 #define VCM_RED_PAYLOAD_TYPE        96
 #define VCM_ULPFEC_PAYLOAD_TYPE     97
@@ -474,9 +472,6 @@
     // Setting External transport
     TbExternalTransport extTransport(*(ptrViENetwork), videoChannel, NULL);
 
-    webrtc::VideoChannelTransport* video_channel_transport =
-        new webrtc::VideoChannelTransport(ptrViENetwork, videoChannel);
-    
     int testMode = 0;
     std::cout << std::endl;
     std::cout << "Enter 1 for testing packet loss and delay with "
@@ -529,17 +524,17 @@
         std::cout << std::endl;
         std::cout << "Using rtp port: " << rtpPort << std::endl;
         std::cout << std::endl;
-        
-        error = video_channel_transport->SetLocalReceiver(rtpPort);
+        error = ptrViENetwork->SetLocalReceiver(videoChannel, rtpPort);
         if (error == -1)
         {
-            printf("ERROR in SetLocalReceiver\n");
+            printf("ERROR in ViENetwork::SetLocalReceiver\n");
             return -1;
         }
-        error = video_channel_transport->SetSendDestination(ipAddress, rtpPort);
+        error = ptrViENetwork->SetSendDestination(videoChannel,
+                                                  ipAddress, rtpPort);
         if (error == -1)
         {
-            printf("ERROR in SetSendDestination\n");
+            printf("ERROR in ViENetwork::SetSendDestination\n");
             return -1;
         }
     }
@@ -642,7 +637,7 @@
         printf("ERROR in ViEBase::DeleteChannel\n");
         return -1;
     }
-    delete video_channel_transport;
+
     int remainingInterfaces = 0;
     remainingInterfaces = ptrViECodec->Release();
     remainingInterfaces += ptrViECapture->Release();
diff --git a/video_engine/test/auto_test/source/vie_autotest_network.cc b/video_engine/test/auto_test/source/vie_autotest_network.cc
new file mode 100644
index 0000000..550bd4f
--- /dev/null
+++ b/video_engine/test/auto_test/source/vie_autotest_network.cc
@@ -0,0 +1,573 @@
+/*
+ *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+//
+// vie_autotest_network.cc
+//
+
+#include "vie_autotest_defines.h"
+#include "vie_autotest.h"
+#include "engine_configurations.h"
+
+#include "tb_capture_device.h"
+#include "tb_external_transport.h"
+#include "tb_interfaces.h"
+#include "tb_video_channel.h"
+
+#if defined(_WIN32)
+#include <qos.h>
+#endif
+
+class ViEAutoTestNetworkObserver: public webrtc::ViENetworkObserver
+{
+public:
+    ViEAutoTestNetworkObserver()
+    {
+    }
+    virtual ~ViEAutoTestNetworkObserver()
+    {
+    }
+    virtual void OnPeriodicDeadOrAlive(const int videoChannel, const bool alive)
+    {
+    }
+    virtual void PacketTimeout(const int videoChannel,
+                               const webrtc::ViEPacketTimeout timeout)
+    {
+    }
+};
+
+void ViEAutoTest::ViENetworkStandardTest()
+{
+    TbInterfaces ViE("ViENetworkStandardTest"); // Create VIE
+    TbCaptureDevice tbCapture(ViE);
+    {
+        // Create a video channel
+        TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
+        tbCapture.ConnectTo(tbChannel.videoChannel);
+
+        RenderCaptureDeviceAndOutputStream(&ViE, &tbChannel, &tbCapture);
+
+        // ***************************************************************
+        // Engine ready. Begin testing class
+        // ***************************************************************
+
+        //
+        // Transport
+        //
+        TbExternalTransport testTransport(*ViE.network, tbChannel.videoChannel,
+                                          NULL);
+        EXPECT_EQ(0, ViE.network->RegisterSendTransport(
+            tbChannel.videoChannel, testTransport));
+        EXPECT_EQ(0, ViE.base->StartReceive(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.base->StartSend(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.rtp_rtcp->SetKeyFrameRequestMethod(
+            tbChannel.videoChannel, webrtc::kViEKeyFrameRequestPliRtcp));
+
+        ViETest::Log("Call started using external transport, video should "
+            "see video in both windows\n");
+        AutoTestSleep(kAutoTestSleepTimeMs);
+
+        EXPECT_EQ(0, ViE.base->StopReceive(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.base->StopSend(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.network->DeregisterSendTransport(
+            tbChannel.videoChannel));
+
+        char myIpAddress[64];
+        memset(myIpAddress, 0, 64);
+        unsigned short rtpPort = 1234;
+        memcpy(myIpAddress, "127.0.0.1", sizeof("127.0.0.1"));
+        EXPECT_EQ(0, ViE.network->SetLocalReceiver(
+            tbChannel.videoChannel, rtpPort, rtpPort + 1, myIpAddress));
+        EXPECT_EQ(0, ViE.network->SetSendDestination(
+            tbChannel.videoChannel, myIpAddress, rtpPort,
+            rtpPort + 1, rtpPort));
+        EXPECT_EQ(0, ViE.base->StartReceive(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.base->StartSend(tbChannel.videoChannel));
+
+        ViETest::Log("Changed to WebRTC SocketTransport, you should still see "
+                     "video in both windows\n");
+        AutoTestSleep(kAutoTestSleepTimeMs);
+
+        EXPECT_EQ(0, ViE.network->SetSourceFilter(
+            tbChannel.videoChannel, rtpPort + 10, rtpPort + 11, myIpAddress));
+        ViETest::Log("Added UDP port filter for incorrect ports, you should "
+                     "not see video in Window2");
+        AutoTestSleep(2000);
+        EXPECT_EQ(0, ViE.network->SetSourceFilter(
+            tbChannel.videoChannel, rtpPort, rtpPort + 1, "123.1.1.0"));
+        ViETest::Log("Added IP filter for incorrect IP address, you should not "
+                     "see video in Window2");
+        AutoTestSleep(2000);
+        EXPECT_EQ(0, ViE.network->SetSourceFilter(
+            tbChannel.videoChannel, rtpPort, rtpPort + 1, myIpAddress));
+        ViETest::Log("Added IP filter for this computer, you should see video "
+                     "in Window2 again\n");
+        AutoTestSleep(kAutoTestSleepTimeMs);
+
+        tbCapture.Disconnect(tbChannel.videoChannel);
+    }
+}
+
+void ViEAutoTest::ViENetworkExtendedTest()
+{
+    //***************************************************************
+    //	Begin create/initialize WebRTC Video Engine for testing
+    //***************************************************************
+
+    TbInterfaces ViE("ViENetworkExtendedTest"); // Create VIE
+    TbCaptureDevice tbCapture(ViE);
+    EXPECT_EQ(0, ViE.render->AddRenderer(
+        tbCapture.captureId, _window1, 0, 0.0, 0.0, 1.0, 1.0));
+    EXPECT_EQ(0, ViE.render->StartRender(tbCapture.captureId));
+
+    {
+        //
+        // ToS
+        //
+        // Create a video channel
+        TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecVP8);
+        tbCapture.ConnectTo(tbChannel.videoChannel);
+        const char* remoteIp = "192.168.200.1";
+        int DSCP = 0;
+        bool useSetSockOpt = false;
+
+        webrtc::VideoCodec videoCodec;
+        EXPECT_EQ(0, ViE.codec->GetSendCodec(
+            tbChannel.videoChannel, videoCodec));
+        videoCodec.maxFramerate = 5;
+        EXPECT_EQ(0, ViE.codec->SetSendCodec(
+            tbChannel.videoChannel, videoCodec));
+
+        //***************************************************************
+        //	Engine ready. Begin testing class
+        //***************************************************************
+
+        char myIpAddress[64];
+        memset(myIpAddress, 0, 64);
+        unsigned short rtpPort = 9000;
+        EXPECT_EQ(0, ViE.network->GetLocalIP(myIpAddress, false));
+        EXPECT_EQ(0, ViE.network->SetLocalReceiver(
+            tbChannel.videoChannel, rtpPort, rtpPort + 1, myIpAddress));
+        EXPECT_EQ(0, ViE.network->SetSendDestination(
+            tbChannel.videoChannel, remoteIp, rtpPort, rtpPort + 1, rtpPort));
+
+        // ToS
+        int tos_result = ViE.network->SetSendToS(tbChannel.videoChannel, 2);
+        EXPECT_EQ(0, tos_result);
+        if (tos_result != 0)
+        {
+            ViETest::Log("ViESetSendToS error!.");
+            ViETest::Log("You must be admin to run these tests.");
+            ViETest::Log("On Win7 and late Vista, you need to right click the "
+                         "exe and choose");
+            ViETest::Log("\"Run as administrator\"\n");
+            getchar();
+        }
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));  // No ToS set
+
+        EXPECT_EQ(0, ViE.base->StartReceive(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.base->StartSend(tbChannel.videoChannel));
+
+        ViETest::Log("Use Wireshark to capture the outgoing video stream and "
+                     "verify ToS settings\n");
+        ViETest::Log(" DSCP set to 0x%x\n", DSCP);
+        AutoTestSleep(1000);
+
+        EXPECT_EQ(0, ViE.network->SetSendToS(tbChannel.videoChannel, 63));
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));  // No ToS set
+        ViETest::Log(" DSCP set to 0x%x\n", DSCP);
+        AutoTestSleep(1000);
+
+        EXPECT_EQ(0, ViE.network->SetSendToS(tbChannel.videoChannel, 0));
+        EXPECT_EQ(0, ViE.network->SetSendToS(tbChannel.videoChannel, 2, true));
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));  // No ToS set
+        ViETest::Log(" DSCP set to 0x%x\n", DSCP);
+        AutoTestSleep(1000);
+
+        EXPECT_EQ(0, ViE.network->SetSendToS(tbChannel.videoChannel, 63, true));
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));  // No ToS set
+        ViETest::Log(" DSCP set to 0x%x\n", DSCP);
+        AutoTestSleep(1000);
+
+        tbCapture.Disconnect(tbChannel.videoChannel);
+    }
+
+    //***************************************************************
+    //	Testing finished. Tear down Video Engine
+    //***************************************************************
+}
+
+void ViEAutoTest::ViENetworkAPITest()
+{
+    //***************************************************************
+    //	Begin create/initialize WebRTC Video Engine for testing
+    //***************************************************************
+
+    TbInterfaces ViE("ViENetworkAPITest"); // Create VIE
+    {
+        // Create a video channel
+        TbVideoChannel tbChannel(ViE, webrtc::kVideoCodecI420);
+
+        //***************************************************************
+        //	Engine ready. Begin testing class
+        //***************************************************************
+
+        //
+        // External transport
+        //
+        TbExternalTransport testTransport(*ViE.network, tbChannel.videoChannel,
+                                          NULL);
+        EXPECT_EQ(0, ViE.network->RegisterSendTransport(
+            tbChannel.videoChannel, testTransport));
+        EXPECT_NE(0, ViE.network->RegisterSendTransport(
+            tbChannel.videoChannel, testTransport));
+
+        // Create a empty RTP packet.
+        unsigned char packet[3000];
+        memset(packet, 0, sizeof(packet));
+        packet[0] = 0x80; // V=2, P=0, X=0, CC=0
+        packet[1] = 0x7C; // M=0, PT = 124 (I420)
+
+        // Create a empty RTCP app packet.
+        unsigned char rtcpacket[3000];
+        memset(rtcpacket,0, sizeof(rtcpacket));
+        rtcpacket[0] = 0x80; // V=2, P=0, X=0, CC=0
+        rtcpacket[1] = 0xCC; // M=0, PT = 204 (RTCP app)
+        rtcpacket[2] = 0x0;
+        rtcpacket[3] = 0x03; // 3 Octets long.
+
+        EXPECT_NE(0, ViE.network->ReceivedRTPPacket(
+            tbChannel.videoChannel, packet, 1500));
+        EXPECT_NE(0, ViE.network->ReceivedRTCPPacket(
+            tbChannel.videoChannel, rtcpacket, 1500));
+        EXPECT_EQ(0, ViE.base->StartReceive(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.network->ReceivedRTPPacket(
+            tbChannel.videoChannel, packet, 1500));
+        EXPECT_EQ(0, ViE.network->ReceivedRTCPPacket(
+            tbChannel.videoChannel, rtcpacket, 1500));
+        EXPECT_NE(0, ViE.network->ReceivedRTPPacket(
+            tbChannel.videoChannel, packet, 11));
+        EXPECT_NE(0, ViE.network->ReceivedRTPPacket(
+            tbChannel.videoChannel, packet, 11));
+        EXPECT_EQ(0, ViE.network->ReceivedRTPPacket(
+            tbChannel.videoChannel, packet, 3000));
+        EXPECT_EQ(0, ViE.network->ReceivedRTPPacket(
+            tbChannel.videoChannel, packet, 3000));
+        EXPECT_EQ(0, ViE.base->StopReceive(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.base->StartSend(tbChannel.videoChannel));
+        EXPECT_NE(0, ViE.network->DeregisterSendTransport(
+            tbChannel.videoChannel));  // Sending
+        EXPECT_EQ(0, ViE.base->StopSend(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.network->DeregisterSendTransport(
+            tbChannel.videoChannel));
+        EXPECT_NE(0, ViE.network->DeregisterSendTransport(
+            tbChannel.videoChannel));  // Already deregistered
+
+        //
+        // Local receiver
+        //
+        EXPECT_EQ(0, ViE.network->SetLocalReceiver(
+            tbChannel.videoChannel, 1234, 1235, "127.0.0.1"));
+        EXPECT_EQ(0, ViE.network->SetLocalReceiver(
+            tbChannel.videoChannel, 1234, 1235, "127.0.0.1"));
+        EXPECT_EQ(0, ViE.network->SetLocalReceiver(
+            tbChannel.videoChannel, 1236, 1237, "127.0.0.1"));
+
+        unsigned short rtpPort = 0;
+        unsigned short rtcpPort = 0;
+        char ipAddress[64];
+        memset(ipAddress, 0, 64);
+        EXPECT_EQ(0, ViE.network->GetLocalReceiver(
+            tbChannel.videoChannel, rtpPort, rtcpPort, ipAddress));
+        EXPECT_EQ(0, ViE.base->StartReceive(tbChannel.videoChannel));
+        EXPECT_NE(0, ViE.network->SetLocalReceiver(
+            tbChannel.videoChannel, 1234, 1235, "127.0.0.1"));
+        EXPECT_EQ(0, ViE.network->GetLocalReceiver(
+            tbChannel.videoChannel, rtpPort, rtcpPort, ipAddress));
+        EXPECT_EQ(0, ViE.base->StopReceive(tbChannel.videoChannel));
+
+        //
+        // Send destination
+        //
+        EXPECT_EQ(0, ViE.network->SetSendDestination(
+            tbChannel.videoChannel, "127.0.0.1", 1234, 1235, 1234, 1235));
+        EXPECT_EQ(0, ViE.network->SetSendDestination(
+            tbChannel.videoChannel, "127.0.0.1", 1236, 1237, 1234, 1235));
+
+        unsigned short sourceRtpPort = 0;
+        unsigned short sourceRtcpPort = 0;
+        EXPECT_EQ(0, ViE.network->GetSendDestination(
+            tbChannel.videoChannel, ipAddress, rtpPort, rtcpPort,
+            sourceRtpPort, sourceRtcpPort));
+        EXPECT_EQ(0, ViE.base->StartSend(tbChannel.videoChannel));
+
+        // Not allowed while sending
+        EXPECT_NE(0, ViE.network->SetSendDestination(
+            tbChannel.videoChannel, "127.0.0.1", 1234, 1235, 1234, 1235));
+        EXPECT_EQ(kViENetworkAlreadySending, ViE.base->LastError());
+
+        EXPECT_EQ(0, ViE.base->StopSend(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.network->SetSendDestination(
+            tbChannel.videoChannel, "127.0.0.1", 1234, 1235, 1234, 1235));
+        EXPECT_EQ(0, ViE.base->StartSend(tbChannel.videoChannel));
+        EXPECT_EQ(0, ViE.network->GetSendDestination(
+            tbChannel.videoChannel, ipAddress, rtpPort, rtcpPort,
+            sourceRtpPort, sourceRtcpPort));
+        EXPECT_EQ(0, ViE.base->StopSend(tbChannel.videoChannel));
+
+        //
+        // Address information
+        //
+
+        // GetSourceInfo: Tested in functional test
+        EXPECT_EQ(0, ViE.network->GetLocalIP(ipAddress, false));
+
+        // TODO(unknown): IPv6
+
+        //
+        // Filter
+        //
+        EXPECT_NE(0, ViE.network->GetSourceFilter(
+            tbChannel.videoChannel, rtpPort, rtcpPort, ipAddress));
+        EXPECT_EQ(0, ViE.network->SetSourceFilter(
+            tbChannel.videoChannel, 1234, 1235, "10.10.10.10"));
+        EXPECT_EQ(0, ViE.network->SetSourceFilter(
+            tbChannel.videoChannel, 1236, 1237, "127.0.0.1"));
+        EXPECT_EQ(0, ViE.network->GetSourceFilter(
+            tbChannel.videoChannel, rtpPort, rtcpPort, ipAddress));
+        EXPECT_EQ(0, ViE.network->SetSourceFilter(
+            tbChannel.videoChannel, 0, 0, NULL));
+        EXPECT_NE(0, ViE.network->GetSourceFilter(
+            tbChannel.videoChannel, rtpPort, rtcpPort, ipAddress));
+    }
+    {
+        TbVideoChannel tbChannel(ViE);  // Create a video channel
+        EXPECT_EQ(0, ViE.network->SetLocalReceiver(
+            tbChannel.videoChannel, 1234));
+
+        int DSCP = 0;
+        bool useSetSockOpt = false;
+        // SetSockOpt should work without a locally bind socket
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));  // No ToS set
+        EXPECT_EQ(0, DSCP);
+
+        // Invalid input
+        EXPECT_NE(0, ViE.network->SetSendToS(tbChannel.videoChannel, -1, true));
+
+        // Invalid input
+        EXPECT_NE(0, ViE.network->SetSendToS(tbChannel.videoChannel, 64, true));
+
+        // Valid
+        EXPECT_EQ(0, ViE.network->SetSendToS(tbChannel.videoChannel, 20, true));
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));
+
+        EXPECT_EQ(20, DSCP);
+        EXPECT_TRUE(useSetSockOpt);
+
+        // Disable
+        EXPECT_EQ(0, ViE.network->SetSendToS(tbChannel.videoChannel, 0, true));
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));
+        EXPECT_EQ(0, DSCP);
+
+        char myIpAddress[64];
+        memset(myIpAddress, 0, 64);
+        // Get local ip to be able to set ToS withtou setSockOpt
+        EXPECT_EQ(0, ViE.network->GetLocalIP(myIpAddress, false));
+        EXPECT_EQ(0, ViE.network->SetLocalReceiver(
+            tbChannel.videoChannel, 1234, 1235, myIpAddress));
+
+        // Invalid input
+        EXPECT_NE(0, ViE.network->SetSendToS(
+            tbChannel.videoChannel, -1, false));
+        EXPECT_NE(0, ViE.network->SetSendToS(
+            tbChannel.videoChannel, 64, false));  // Invalid input
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));  // No ToS set
+        EXPECT_EQ(0, DSCP);
+        int tos_result = ViE.network->SetSendToS(
+            tbChannel.videoChannel, 20, false);  // Valid
+        EXPECT_EQ(0, tos_result);
+        if (tos_result != 0)
+        {
+            ViETest::Log("ViESetSendToS error!.");
+            ViETest::Log("You must be admin to run these tests.");
+            ViETest::Log("On Win7 and late Vista, you need to right click the "
+                         "exe and choose");
+            ViETest::Log("\"Run as administrator\"\n");
+            getchar();
+        }
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));
+        EXPECT_EQ(20, DSCP);
+#ifdef _WIN32
+        EXPECT_FALSE(useSetSockOpt);
+#else // useSetSockOpt is true on Linux and Mac
+        EXPECT_TRUE(useSetSockOpt);
+#endif
+        EXPECT_EQ(0, ViE.network->SetSendToS(tbChannel.videoChannel, 0, false));
+        EXPECT_EQ(0, ViE.network->GetSendToS(
+            tbChannel.videoChannel, DSCP, useSetSockOpt));
+        EXPECT_EQ(0, DSCP);
+    }
+    {
+        // From qos.h. (*) -> supported by ViE
+        //
+        //  #define SERVICETYPE_NOTRAFFIC               0x00000000
+        //  #define SERVICETYPE_BESTEFFORT              0x00000001 (*)
+        //  #define SERVICETYPE_CONTROLLEDLOAD          0x00000002 (*)
+        //  #define SERVICETYPE_GUARANTEED              0x00000003 (*)
+        //  #define SERVICETYPE_NETWORK_UNAVAILABLE     0x00000004
+        //  #define SERVICETYPE_GENERAL_INFORMATION     0x00000005
+        //  #define SERVICETYPE_NOCHANGE                0x00000006
+        //  #define SERVICETYPE_NONCONFORMING           0x00000009
+        //  #define SERVICETYPE_NETWORK_CONTROL         0x0000000A
+        //  #define SERVICETYPE_QUALITATIVE             0x0000000D (*)
+        //
+        //  #define SERVICE_BESTEFFORT                  0x80010000
+        //  #define SERVICE_CONTROLLEDLOAD              0x80020000
+        //  #define SERVICE_GUARANTEED                  0x80040000
+        //  #define SERVICE_QUALITATIVE                 0x80200000
+
+        TbVideoChannel tbChannel(ViE);  // Create a video channel
+
+
+#if defined(_WIN32)
+        // These tests are disabled since they currently fail on Windows.
+        // Exact reason is unkown.
+        // See https://code.google.com/p/webrtc/issues/detail?id=1266.
+        // TODO(mflodman): remove these APIs?
+
+        //// No socket
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_BESTEFFORT));
+
+        //EXPECT_EQ(0, ViE.network->SetLocalReceiver(
+        //    tbChannel.videoChannel, 1234));
+
+        //// Sender not initialized
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_BESTEFFORT));
+        //EXPECT_EQ(0, ViE.network->SetSendDestination(
+        //    tbChannel.videoChannel, "127.0.0.1", 12345));
+
+        //// Try to set all non-supported service types
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_NOTRAFFIC));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_NETWORK_UNAVAILABLE));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_GENERAL_INFORMATION));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_NOCHANGE));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_NONCONFORMING));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_NOTRAFFIC));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_NETWORK_CONTROL));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICE_BESTEFFORT));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICE_CONTROLLEDLOAD));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICE_GUARANTEED));
+        //EXPECT_NE(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICE_QUALITATIVE));
+
+        //// Loop through valid service settings
+        //bool enabled = false;
+        //int serviceType = 0;
+        //int overrideDSCP = 0;
+
+        //EXPECT_EQ(0, ViE.network->GetSendGQoS(
+        //    tbChannel.videoChannel, enabled, serviceType, overrideDSCP));
+        //EXPECT_FALSE(enabled);
+        //EXPECT_EQ(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_BESTEFFORT));
+        //EXPECT_EQ(0, ViE.network->GetSendGQoS(
+        //    tbChannel.videoChannel, enabled, serviceType, overrideDSCP));
+        //EXPECT_TRUE(enabled);
+        //EXPECT_EQ(SERVICETYPE_BESTEFFORT, serviceType);
+        //EXPECT_FALSE(overrideDSCP);
+
+        //EXPECT_EQ(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_CONTROLLEDLOAD));
+        //EXPECT_EQ(0, ViE.network->GetSendGQoS(
+        //    tbChannel.videoChannel, enabled, serviceType, overrideDSCP));
+        //EXPECT_TRUE(enabled);
+        //EXPECT_EQ(SERVICETYPE_CONTROLLEDLOAD, serviceType);
+        //EXPECT_FALSE(overrideDSCP);
+
+        //EXPECT_EQ(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_GUARANTEED));
+        //EXPECT_EQ(0, ViE.network->GetSendGQoS(
+        //    tbChannel.videoChannel, enabled, serviceType, overrideDSCP));
+        //EXPECT_TRUE(enabled);
+        //EXPECT_EQ(SERVICETYPE_GUARANTEED, serviceType);
+        //EXPECT_FALSE(overrideDSCP);
+
+        //EXPECT_EQ(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, true, SERVICETYPE_QUALITATIVE));
+        //EXPECT_EQ(0, ViE.network->GetSendGQoS(
+        //    tbChannel.videoChannel, enabled, serviceType, overrideDSCP));
+        //EXPECT_TRUE(enabled);
+        //EXPECT_EQ(SERVICETYPE_QUALITATIVE, serviceType);
+        //EXPECT_FALSE(overrideDSCP);
+
+        //EXPECT_EQ(0, ViE.network->SetSendGQoS(
+        //    tbChannel.videoChannel, false, SERVICETYPE_QUALITATIVE));
+        //EXPECT_EQ(0, ViE.network->GetSendGQoS(
+        //    tbChannel.videoChannel, enabled, serviceType, overrideDSCP));
+        //EXPECT_FALSE(enabled);
+#endif
+    }
+    {
+        //
+        // MTU and packet burst
+        //
+        // Create a video channel
+        TbVideoChannel tbChannel(ViE);
+        // Invalid input
+        EXPECT_NE(0, ViE.network->SetMTU(tbChannel.videoChannel, 1600));
+        // Valid input
+        EXPECT_EQ(0, ViE.network->SetMTU(tbChannel.videoChannel, 800));
+
+        //
+        // Observer and timeout
+        //
+        ViEAutoTestNetworkObserver vieTestObserver;
+        EXPECT_EQ(0, ViE.network->RegisterObserver(
+            tbChannel.videoChannel, vieTestObserver));
+        EXPECT_NE(0, ViE.network->RegisterObserver(
+            tbChannel.videoChannel, vieTestObserver));
+        EXPECT_EQ(0, ViE.network->SetPeriodicDeadOrAliveStatus(
+            tbChannel.videoChannel, true)); // No observer
+        EXPECT_EQ(0, ViE.network->DeregisterObserver(tbChannel.videoChannel));
+
+        EXPECT_NE(0, ViE.network->DeregisterObserver(tbChannel.videoChannel));
+        EXPECT_NE(0, ViE.network->SetPeriodicDeadOrAliveStatus(
+            tbChannel.videoChannel, true)); // No observer
+
+        // Packet timout notification
+        EXPECT_EQ(0, ViE.network->SetPacketTimeoutNotification(
+            tbChannel.videoChannel, true, 10));
+    }
+
+    //***************************************************************
+    //	Testing finished. Tear down Video Engine
+    //***************************************************************
+}
diff --git a/video_engine/test/auto_test/source/vie_autotest_record.cc b/video_engine/test/auto_test/source/vie_autotest_record.cc
index eb378c8..15b2a83 100644
--- a/video_engine/test/auto_test/source/vie_autotest_record.cc
+++ b/video_engine/test/auto_test/source/vie_autotest_record.cc
@@ -17,22 +17,20 @@
 #include <stdio.h>
 #include <fstream>
 
-#include "webrtc/common_types.h"
-#include "webrtc/system_wrappers/interface/tick_util.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-#include "webrtc/video_engine/test/libvietest/include/tb_external_transport.h"
-#include "webrtc/voice_engine/include/voe_base.h"
-#include "webrtc/video_engine/test/auto_test/interface/vie_autotest_defines.h"
-#include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
-#include "webrtc/video_engine/include/vie_base.h"
-#include "webrtc/video_engine/include/vie_capture.h"
-#include "webrtc/video_engine/include/vie_codec.h"
-#include "webrtc/video_engine/include/vie_file.h"
-#include "webrtc/video_engine/include/vie_network.h"
-#include "webrtc/video_engine/include/vie_render.h"
-#include "webrtc/video_engine/include/vie_rtp_rtcp.h"
-#include "webrtc/voice_engine/include/voe_network.h"
-#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
+#include "common_types.h"
+#include "video_engine/test/libvietest/include/tb_external_transport.h"
+#include "voice_engine/include/voe_base.h"
+#include "video_engine/test/auto_test/interface/vie_autotest_defines.h"
+#include "video_engine/test/auto_test/interface/vie_autotest.h"
+#include "video_engine/include/vie_base.h"
+#include "video_engine/include/vie_capture.h"
+#include "video_engine/include/vie_codec.h"
+#include "video_engine/include/vie_file.h"
+#include "video_engine/include/vie_network.h"
+#include "video_engine/include/vie_render.h"
+#include "video_engine/include/vie_rtp_rtcp.h"
+#include "voice_engine/include/voe_rtp_rtcp.h"
+#include "system_wrappers/interface/tick_util.h"
 
 #define VCM_RED_PAYLOAD_TYPE            96
 #define VCM_ULPFEC_PAYLOAD_TYPE         97
@@ -141,8 +139,6 @@
   webrtc::VoECodec* voe_codec = webrtc::VoECodec::GetInterface(voe);
   webrtc::VoEAudioProcessing* voe_apm =
        webrtc::VoEAudioProcessing::GetInterface(voe);
-  webrtc::VoENetwork* voe_network =
-    webrtc::VoENetwork::GetInterface(voe);
 
   // Get the audio device for the call.
   memset(audio_capture_device_name, 0, KMaxUniqueIdLength);
@@ -151,23 +147,20 @@
                   audio_capture_device_index, audio_playbackDeviceName,
                   audio_playback_device_index);
 
+
   // Get the audio codec for the call.
   memset(static_cast<void*>(&audio_codec), 0, sizeof(audio_codec));
   GetAudioCodecRecord(voe_codec, audio_codec);
 
   audio_channel = voe_base->CreateChannel();
-
-  webrtc::scoped_ptr<webrtc::VoiceChannelTransport> voice_channel_transport(
-      new webrtc::VoiceChannelTransport(voe_network, audio_channel));
-
-  voice_channel_transport->SetSendDestination(ipAddress, audio_tx_port);
-  voice_channel_transport->SetLocalReceiver(audio_rx_port);
-
-  voe_hardware->SetRecordingDevice(audio_capture_device_index);
-  voe_hardware->SetPlayoutDevice(audio_playback_device_index);
-  voe_codec->SetSendCodec(audio_channel, audio_codec);
-  voe_apm->SetAgcStatus(true, webrtc::kAgcDefault);
-  voe_apm->SetNsStatus(true, webrtc::kNsHighSuppression);
+  error = voe_base->SetSendDestination(audio_channel, audio_tx_port,
+                                        ipAddress);
+  error = voe_base->SetLocalReceiver(audio_channel, audio_rx_port);
+  error = voe_hardware->SetRecordingDevice(audio_capture_device_index);
+  error = voe_hardware->SetPlayoutDevice(audio_playback_device_index);
+  error = voe_codec->SetSendCodec(audio_channel, audio_codec);
+  error = voe_apm->SetAgcStatus(true, webrtc::kAgcDefault);
+  error = voe_apm->SetNsStatus(true, webrtc::kNsHighSuppression);
 
   //
   // List available capture devices, allocate and connect.
@@ -359,17 +352,18 @@
     printf("ERROR in ViENetwork::GetInterface\n");
     return -1;
   }
-  webrtc::VideoChannelTransport* video_channel_transport =
-      new webrtc::VideoChannelTransport(ptrViENetwork, videoChannel);
 
-  error = video_channel_transport->SetSendDestination(ipAddress, rtpPort);
+  // Setting External transport
+  TbExternalTransport extTransport(*(ptrViENetwork), videoChannel, NULL);
+  error = ptrViENetwork->SetLocalReceiver(videoChannel, rtpPort);
   if (error == -1) {
-    printf("ERROR in SetSendDestination\n");
+    printf("ERROR in ViENetwork::SetLocalReceiver\n");
     return -1;
   }
-  error = video_channel_transport->SetLocalReceiver(rtpPort);
+  error = ptrViENetwork->SetSendDestination(videoChannel,
+                                            ipAddress, rtpPort);
   if (error == -1) {
-    printf("ERROR in SetLocalReceiver\n");
+    printf("ERROR in ViENetwork::SetSendDestination\n");
     return -1;
   }
 
@@ -526,7 +520,6 @@
     printf("ERROR in ViEBase::DeleteChannel\n");
     return -1;
   }
-  delete video_channel_transport;
 
   int remainingInterfaces = 0;
   remainingInterfaces = ptrViECodec->Release();
@@ -539,6 +532,7 @@
     printf("ERROR: Could not release all interfaces\n");
     return -1;
   }
+
   bool deleted = webrtc::VideoEngine::Delete(ptrViE);
   if (deleted == false) {
     printf("ERROR in VideoEngine::Delete\n");
@@ -570,7 +564,7 @@
 }
 
 bool GetAudioCodecRecord(webrtc::VoECodec* voe_codec,
-                         webrtc::CodecInst& audio_codec) {
+                       webrtc::CodecInst& audio_codec) {
   int error = 0;
   int number_of_errors = 0;
   memset(&audio_codec, 0, sizeof(webrtc::CodecInst));
diff --git a/video_engine/test/auto_test/vie_auto_test.gypi b/video_engine/test/auto_test/vie_auto_test.gypi
index 99f8dda..984cc75 100644
--- a/video_engine/test/auto_test/vie_auto_test.gypi
+++ b/video_engine/test/auto_test/vie_auto_test.gypi
@@ -20,7 +20,6 @@
         '<(DEPTH)/third_party/google-gflags/google-gflags.gyp:google-gflags',
         '<(webrtc_root)/test/metrics.gyp:metrics',
         '<(webrtc_root)/test/test.gyp:test_support',
-        '<(webrtc_root)/test/udp_transport.gyp:udp_transport',
         '<(webrtc_root)/test/libtest/libtest.gyp:libtest',
         'video_engine_core',
         'libvietest',
@@ -82,6 +81,7 @@
         'source/vie_autotest_image_process.cc',
         'source/vie_autotest_loopback.cc',
         'source/vie_autotest_main.cc',
+        'source/vie_autotest_network.cc',
         'source/vie_autotest_render.cc',
         'source/vie_autotest_record.cc',
         'source/vie_autotest_rtp_rtcp.cc',
diff --git a/video_engine/test/libvietest/include/tb_video_channel.h b/video_engine/test/libvietest/include/tb_video_channel.h
index c3a458a..5c7e6f8 100644
--- a/video_engine/test/libvietest/include/tb_video_channel.h
+++ b/video_engine/test/libvietest/include/tb_video_channel.h
@@ -11,39 +11,32 @@
 #ifndef WEBRTC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_INTERFACE_TB_VIDEO_CHANNEL_H_
 #define WEBRTC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_INTERFACE_TB_VIDEO_CHANNEL_H_
 
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/video_engine/test/libvietest/include/tb_interfaces.h"
+#include "video_engine/test/libvietest/include/tb_interfaces.h"
 
-namespace webrtc {
-class VideoChannelTransport;
-} // namespace webrtc
+class TbVideoChannel
+{
+public:
+    TbVideoChannel(TbInterfaces& Engine,
+                   webrtc::VideoCodecType sendCodec = webrtc::kVideoCodecVP8,
+                   int width = 352, int height = 288, int frameRate = 30,
+                   int startBitrate = 300);
 
-class TbVideoChannel {
- public:
-  TbVideoChannel(TbInterfaces& Engine,
-                 webrtc::VideoCodecType sendCodec = webrtc::kVideoCodecVP8,
-                 int width = 352, int height = 288, int frameRate = 30,
-                 int startBitrate = 300);
+    ~TbVideoChannel(void);
 
-  ~TbVideoChannel(void);
+    void SetFrameSettings(int width, int height, int frameRate);
 
-  void SetFrameSettings(int width, int height, int frameRate);
+    void StartSend(const unsigned short rtpPort = 11000,
+                   const char* ipAddress = "127.0.0.1");
 
-  void StartSend(const unsigned short rtpPort = 11000,
-                 const char* ipAddress = "127.0.0.1");
+    void StopSend();
 
-  void StopSend();
+    void StartReceive(const unsigned short rtpPort = 11000);
 
-  void StartReceive(const unsigned short rtpPort = 11000);
+    void StopReceive();
 
-  void StopReceive();
-
-  int videoChannel;
-
- private:
-  TbInterfaces& ViE;
-  webrtc::scoped_ptr<webrtc::VideoChannelTransport> channel_transport_;
+    int videoChannel;
+private:
+    TbInterfaces& ViE;
 };
 
-
 #endif  // WEBRTC_VIDEO_ENGINE_MAIN_TEST_AUTOTEST_INTERFACE_TB_VIDEO_CHANNEL_H_
diff --git a/video_engine/test/libvietest/testbed/tb_video_channel.cc b/video_engine/test/libvietest/testbed/tb_video_channel.cc
index fe3a438..3359f18 100644
--- a/video_engine/test/libvietest/testbed/tb_video_channel.cc
+++ b/video_engine/test/libvietest/testbed/tb_video_channel.cc
@@ -11,73 +11,82 @@
 #include "video_engine/test/libvietest/include/tb_video_channel.h"
 
 #include "gtest/gtest.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
 
 TbVideoChannel::TbVideoChannel(TbInterfaces& Engine,
                                webrtc::VideoCodecType sendCodec, int width,
-                               int height, int frameRate, int startBitrate)
-    : videoChannel(-1),
-      ViE(Engine) {
-  EXPECT_EQ(0, ViE.base->CreateChannel(videoChannel));
-  channel_transport_.reset(new webrtc::VideoChannelTransport(
-      ViE.network, videoChannel));
+                               int height, int frameRate, int startBitrate) :
+    videoChannel(-1),  ViE(Engine)
+{
+    EXPECT_EQ(0, ViE.base->CreateChannel(videoChannel));
 
-  webrtc::VideoCodec videoCodec;
-  memset(&videoCodec, 0, sizeof(webrtc::VideoCodec));
-  bool sendCodecSet = false;
-  for (int idx = 0; idx < ViE.codec->NumberOfCodecs(); idx++) {
-    EXPECT_EQ(0, ViE.codec->GetCodec(idx, videoCodec));
+    webrtc::VideoCodec videoCodec;
+    memset(&videoCodec, 0, sizeof(webrtc::VideoCodec));
+    bool sendCodecSet = false;
+    for (int idx = 0; idx < ViE.codec->NumberOfCodecs(); idx++)
+    {
+        EXPECT_EQ(0, ViE.codec->GetCodec(idx, videoCodec));
+        videoCodec.width = width;
+        videoCodec.height = height;
+        videoCodec.maxFramerate = frameRate;
+
+        if (videoCodec.codecType == sendCodec && sendCodecSet == false)
+        {
+            if(videoCodec.codecType != webrtc::kVideoCodecI420 )
+            {
+                videoCodec.startBitrate = startBitrate;
+                videoCodec.maxBitrate = startBitrate * 3;
+            }
+            EXPECT_EQ(0, ViE.codec->SetSendCodec(videoChannel, videoCodec));
+            sendCodecSet = true;
+        }
+        if (videoCodec.codecType == webrtc::kVideoCodecVP8)
+        {
+            videoCodec.width = 352;
+            videoCodec.height = 288;
+        }
+        EXPECT_EQ(0, ViE.codec->SetReceiveCodec(videoChannel, videoCodec));
+    }
+    EXPECT_TRUE(sendCodecSet);
+}
+
+TbVideoChannel::~TbVideoChannel(void)
+{
+    EXPECT_EQ(0, ViE.base->DeleteChannel(videoChannel));
+}
+
+void TbVideoChannel::StartSend(const unsigned short rtpPort /*= 11000*/,
+                               const char* ipAddress /*= "127.0.0.1"*/)
+{
+    EXPECT_EQ(0, ViE.network->SetSendDestination(videoChannel, ipAddress,
+                                                 rtpPort));
+
+    EXPECT_EQ(0, ViE.base->StartSend(videoChannel));
+}
+
+void TbVideoChannel::SetFrameSettings(int width, int height, int frameRate)
+{
+    webrtc::VideoCodec videoCodec;
+    EXPECT_EQ(0, ViE.codec->GetSendCodec(videoChannel, videoCodec));
     videoCodec.width = width;
     videoCodec.height = height;
     videoCodec.maxFramerate = frameRate;
 
-    if (videoCodec.codecType == sendCodec && sendCodecSet == false) {
-      if (videoCodec.codecType != webrtc::kVideoCodecI420) {
-        videoCodec.startBitrate = startBitrate;
-        videoCodec.maxBitrate = startBitrate * 3;
-      }
-      EXPECT_EQ(0, ViE.codec->SetSendCodec(videoChannel, videoCodec));
-      sendCodecSet = true;
-    }
-    if (videoCodec.codecType == webrtc::kVideoCodecVP8) {
-      videoCodec.width = 352;
-      videoCodec.height = 288;
-    }
+    EXPECT_EQ(0, ViE.codec->SetSendCodec(videoChannel, videoCodec));
     EXPECT_EQ(0, ViE.codec->SetReceiveCodec(videoChannel, videoCodec));
-  }
-  EXPECT_TRUE(sendCodecSet);
 }
 
-TbVideoChannel::~TbVideoChannel() {
-  EXPECT_EQ(0, ViE.base->DeleteChannel(videoChannel));
+void TbVideoChannel::StopSend()
+{
+    EXPECT_EQ(0, ViE.base->StopSend(videoChannel));
 }
 
-void TbVideoChannel::StartSend(const unsigned short rtp_port,
-                               const char* ip_address) {
-  EXPECT_EQ(0, channel_transport_->SetSendDestination(ip_address, rtp_port));
-  EXPECT_EQ(0, ViE.base->StartSend(videoChannel));
+void TbVideoChannel::StartReceive(const unsigned short rtpPort /*= 11000*/)
+{
+    EXPECT_EQ(0, ViE.network->SetLocalReceiver(videoChannel, rtpPort));
+    EXPECT_EQ(0, ViE.base->StartReceive(videoChannel));
 }
 
-void TbVideoChannel::SetFrameSettings(int width, int height, int frameRate) {
-  webrtc::VideoCodec videoCodec;
-  EXPECT_EQ(0, ViE.codec->GetSendCodec(videoChannel, videoCodec));
-  videoCodec.width = width;
-  videoCodec.height = height;
-  videoCodec.maxFramerate = frameRate;
-
-  EXPECT_EQ(0, ViE.codec->SetSendCodec(videoChannel, videoCodec));
-  EXPECT_EQ(0, ViE.codec->SetReceiveCodec(videoChannel, videoCodec));
-}
-
-void TbVideoChannel::StopSend() {
-  EXPECT_EQ(0, ViE.base->StopSend(videoChannel));
-}
-
-void TbVideoChannel::StartReceive(unsigned short rtp_port) {
-  EXPECT_EQ(0, channel_transport_->SetLocalReceiver(rtp_port));
-  EXPECT_EQ(0, ViE.base->StartReceive(videoChannel));
-}
-
-void TbVideoChannel::StopReceive() {
-  EXPECT_EQ(0, ViE.base->StopReceive(videoChannel));
+void TbVideoChannel::StopReceive()
+{
+    EXPECT_EQ(0, ViE.base->StopReceive(videoChannel));
 }
diff --git a/video_engine/video_engine_core.gypi b/video_engine/video_engine_core.gypi
index d8e2986..8f28ef6 100644
--- a/video_engine/video_engine_core.gypi
+++ b/video_engine/video_engine_core.gypi
@@ -26,6 +26,7 @@
         # ModulesShared
         '<(webrtc_root)/modules/modules.gyp:media_file',
         '<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
+        '<(webrtc_root)/modules/modules.gyp:udp_transport',
         '<(webrtc_root)/modules/modules.gyp:webrtc_utility',
 
         # ModulesVideo
diff --git a/video_engine/vie_base_impl.cc b/video_engine/vie_base_impl.cc
index e35a216..6348bc4 100644
--- a/video_engine/vie_base_impl.cc
+++ b/video_engine/vie_base_impl.cc
@@ -325,6 +325,14 @@
     shared_data_.SetLastError(kViEBaseInvalidChannelId);
     return -1;
   }
+  if (vie_channel->Receiving()) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_.instance_id(), video_channel),
+                 "%s: Channel %d already receive.", __FUNCTION__,
+                 video_channel);
+    shared_data_.SetLastError(kViEBaseAlreadyReceiving);
+    return -1;
+  }
   if (vie_channel->StartReceive() != 0) {
     shared_data_.SetLastError(kViEBaseUnknownError);
     return -1;
diff --git a/video_engine/vie_channel.cc b/video_engine/vie_channel.cc
index cb1aada..a93530a 100644
--- a/video_engine/vie_channel.cc
+++ b/video_engine/vie_channel.cc
@@ -16,6 +16,7 @@
 #include "common_video/libyuv/include/webrtc_libyuv.h"
 #include "modules/pacing/include/paced_sender.h"
 #include "modules/rtp_rtcp/interface/rtp_rtcp.h"
+#include "modules/udp_transport/interface/udp_transport.h"
 #include "modules/utility/interface/process_thread.h"
 #include "modules/video_coding/main/interface/video_coding.h"
 #include "modules/video_processing/main/interface/video_processing.h"
@@ -71,6 +72,10 @@
       rtp_rtcp_cs_(CriticalSectionWrapper::CreateCriticalSection()),
       default_rtp_rtcp_(default_rtp_rtcp),
       rtp_rtcp_(NULL),
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+      socket_transport_(*UdpTransport::Create(
+          ViEModuleId(engine_id, channel_id), num_socket_threads_)),
+#endif
       vcm_(*VideoCodingModule::Create(ViEModuleId(engine_id, channel_id))),
       vie_receiver_(channel_id, &vcm_, remote_bitrate_estimator),
       vie_sender_(channel_id),
@@ -207,6 +212,9 @@
                channel_id_, engine_id_);
 
   // Make sure we don't get more callbacks from the RTP module.
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  socket_transport_.StopReceiving();
+#endif
   module_process_thread_.DeRegisterModule(rtp_rtcp_.get());
   module_process_thread_.DeRegisterModule(&vcm_);
   module_process_thread_.DeRegisterModule(&vie_sync_);
@@ -225,6 +233,10 @@
   if (decode_thread_) {
     StopDecodeThread();
   }
+  // Release modules.
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  UdpTransport::Destroy(&socket_transport_);
+#endif
   VideoCodingModule::Destroy(&vcm_);
 }
 
@@ -1276,16 +1288,265 @@
   }
 }
 
+WebRtc_Word32 ViEChannel::SetLocalReceiver(const WebRtc_UWord16 rtp_port,
+                                           const WebRtc_UWord16 rtcp_port,
+                                           const char* ip_address) {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+
+  callback_cs_->Enter();
+  if (external_transport_) {
+    callback_cs_->Leave();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: external transport registered", __FUNCTION__);
+    return -1;
+  }
+  callback_cs_->Leave();
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.Receiving()) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: already receiving", __FUNCTION__);
+    return -1;
+  }
+
+  const char* multicast_ip_address = NULL;
+  if (socket_transport_.InitializeReceiveSockets(&vie_receiver_, rtp_port,
+                                                 ip_address,
+                                                 multicast_ip_address,
+                                                 rtcp_port) != 0) {
+    WebRtc_Word32 socket_error = socket_transport_.LastError();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: could not initialize receive sockets. Socket error: %d",
+                 __FUNCTION__, socket_error);
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::GetLocalReceiver(WebRtc_UWord16* rtp_port,
+                                           WebRtc_UWord16* rtcp_port,
+                                           char* ip_address) const {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+
+  callback_cs_->Enter();
+  if (external_transport_) {
+    callback_cs_->Leave();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: external transport registered", __FUNCTION__);
+    return -1;
+  }
+  callback_cs_->Leave();
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.ReceiveSocketsInitialized() == false) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: receive sockets not initialized", __FUNCTION__);
+    return -1;
+  }
+
+  char multicast_ip_address[UdpTransport::kIpAddressVersion6Length];
+  if (socket_transport_.ReceiveSocketInformation(ip_address, *rtp_port,
+                                                 *rtcp_port,
+                                                 multicast_ip_address) != 0) {
+    WebRtc_Word32 socket_error = socket_transport_.LastError();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+      "%s: could not get receive socket information. Socket error: %d",
+      __FUNCTION__, socket_error);
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::SetSendDestination(
+    const char* ip_address,
+    const WebRtc_UWord16 rtp_port,
+    const WebRtc_UWord16 rtcp_port,
+    const WebRtc_UWord16 source_rtp_port,
+    const WebRtc_UWord16 source_rtcp_port) {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+
+  callback_cs_->Enter();
+  if (external_transport_) {
+    callback_cs_->Leave();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: external transport registered", __FUNCTION__);
+    return -1;
+  }
+  callback_cs_->Leave();
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  const bool is_ipv6 = socket_transport_.IpV6Enabled();
+  if (UdpTransport::IsIpAddressValid(ip_address, is_ipv6) == false) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: Not a valid IP address: %s", __FUNCTION__, ip_address);
+    return -1;
+  }
+  if (socket_transport_.InitializeSendSockets(ip_address, rtp_port,
+                                              rtcp_port)!= 0) {
+    WebRtc_Word32 socket_error = socket_transport_.LastError();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: could not initialize send socket. Socket error: %d",
+                 __FUNCTION__, socket_error);
+    return -1;
+  }
+
+  if (source_rtp_port != 0) {
+    WebRtc_UWord16 receive_rtp_port = 0;
+    WebRtc_UWord16 receive_rtcp_port = 0;
+    if (socket_transport_.ReceiveSocketInformation(NULL, receive_rtp_port,
+                                                   receive_rtcp_port,
+                                                   NULL) != 0) {
+      WebRtc_Word32 socket_error = socket_transport_.LastError();
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+        "%s: could not get receive port information. Socket error: %d",
+        __FUNCTION__, socket_error);
+      return -1;
+    }
+    // Initialize an extra socket only if send port differs from receive
+    // port.
+    if (source_rtp_port != receive_rtp_port) {
+      if (socket_transport_.InitializeSourcePorts(source_rtp_port,
+                                                  source_rtcp_port) != 0) {
+        WebRtc_Word32 socket_error = socket_transport_.LastError();
+        WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                     "%s: could not set source ports. Socket error: %d",
+                     __FUNCTION__, socket_error);
+        return -1;
+      }
+    }
+  }
+  vie_sender_.RegisterSendTransport(&socket_transport_);
+
+  // Workaround to avoid SSRC colision detection in loppback tests.
+  if (!is_ipv6) {
+    WebRtc_UWord32 local_host_address = 0;
+    const WebRtc_UWord32 current_ip_address =
+        UdpTransport::InetAddrIPV4(ip_address);
+
+    if ((UdpTransport::LocalHostAddress(local_host_address) == 0 &&
+        local_host_address == current_ip_address) ||
+        strncmp("127.0.0.1", ip_address, 9) == 0) {
+      rtp_rtcp_->SetSSRC(0xFFFFFFFF);
+      WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "Running in loopback. Forcing fixed SSRC");
+    }
+  } else {
+    char local_host_address[16];
+    char current_ip_address[16];
+
+    WebRtc_Word32 conv_result =
+      UdpTransport::LocalHostAddressIPV6(local_host_address);
+    conv_result += socket_transport_.InetPresentationToNumeric(
+        23, ip_address, current_ip_address);
+    if (conv_result == 0) {
+      bool local_host = true;
+      for (WebRtc_Word32 i = 0; i < 16; i++) {
+        if (local_host_address[i] != current_ip_address[i]) {
+          local_host = false;
+          break;
+        }
+      }
+      if (!local_host) {
+        local_host = true;
+        for (WebRtc_Word32 i = 0; i < 15; i++) {
+          if (current_ip_address[i] != 0) {
+            local_host = false;
+            break;
+          }
+        }
+        if (local_host == true && current_ip_address[15] != 1) {
+          local_host = false;
+        }
+      }
+      if (local_host) {
+        rtp_rtcp_->SetSSRC(0xFFFFFFFF);
+        WEBRTC_TRACE(kTraceStateInfo, kTraceVideo,
+                     ViEId(engine_id_, channel_id_),
+                     "Running in loopback. Forcing fixed SSRC");
+      }
+    }
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo,
+               ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::GetSendDestination(
+    char* ip_address,
+    WebRtc_UWord16* rtp_port,
+    WebRtc_UWord16* rtcp_port,
+    WebRtc_UWord16* source_rtp_port,
+    WebRtc_UWord16* source_rtcp_port) const {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+
+  callback_cs_->Enter();
+  if (external_transport_) {
+    callback_cs_->Leave();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: external transport registered", __FUNCTION__);
+    return -1;
+  }
+  callback_cs_->Leave();
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.SendSocketsInitialized() == false) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: send sockets not initialized", __FUNCTION__);
+    return -1;
+  }
+  if (socket_transport_.SendSocketInformation(ip_address, *rtp_port,
+                                              *rtcp_port) != 0) {
+    WebRtc_Word32 socket_error = socket_transport_.LastError();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+      "%s: could not get send socket information. Socket error: %d",
+      __FUNCTION__, socket_error);
+    return -1;
+  }
+  *source_rtp_port = 0;
+  *source_rtcp_port = 0;
+  if (socket_transport_.SourcePortsInitialized()) {
+    socket_transport_.SourcePorts(*source_rtp_port, *source_rtcp_port);
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+      "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
 WebRtc_Word32 ViEChannel::StartSend() {
   CriticalSectionScoped cs(callback_cs_.get());
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
                "%s", __FUNCTION__);
 
-  if (!external_transport_) {  
-    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),  
-                 "%s: send sockets not initialized", __FUNCTION__); 
-    return -1;  
-  } 
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (!external_transport_) {
+    if (socket_transport_.SendSocketsInitialized() == false) {
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: send sockets not initialized", __FUNCTION__);
+      return -1;
+    }
+  }
+#endif
   rtp_rtcp_->SetSendingMediaStatus(true);
 
   if (rtp_rtcp_->Sending()) {
@@ -1354,10 +1615,35 @@
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
                __FUNCTION__);
 
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (!external_transport_) {
+    if (socket_transport_.Receiving()) {
+      // Warning, don't return error.
+      WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: already receiving", __FUNCTION__);
+      return 0;
+    }
+    if (socket_transport_.ReceiveSocketsInitialized() == false) {
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: receive sockets not initialized", __FUNCTION__);
+      return -1;
+    }
+    if (socket_transport_.StartReceiving(kViENumReceiveSocketBuffers) != 0) {
+      WebRtc_Word32 socket_error = socket_transport_.LastError();
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+        "%s: could not get receive socket information. Socket error:%d",
+        __FUNCTION__, socket_error);
+      return -1;
+    }
+  }
+#endif
   if (StartDecodeThread() != 0) {
     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
                  "%s: could not start decoder thread", __FUNCTION__);
 
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    socket_transport_.StopReceiving();
+#endif
     vie_receiver_.StopReceive();
     return -1;
   }
@@ -1373,12 +1659,100 @@
   vie_receiver_.StopReceive();
   StopDecodeThread();
   vcm_.ResetDecoder();
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    if (external_transport_) {
+      return 0;
+    }
+  }
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.Receiving() == false) {
+    // Warning, don't return error
+    WEBRTC_TRACE(kTraceWarning, kTraceVideo,
+                 ViEId(engine_id_, channel_id_), "%s: not receiving",
+                 __FUNCTION__);
+    return 0;
+  }
+  if (socket_transport_.StopReceiving() != 0) {
+    WebRtc_Word32 socket_error = socket_transport_.LastError();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: Socket error: %d", __FUNCTION__, socket_error);
+    return -1;
+  }
+#endif
+
   return 0;
 }
 
+bool ViEChannel::Receiving() {
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  return socket_transport_.Receiving();
+#else
+  return false;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::GetSourceInfo(WebRtc_UWord16* rtp_port,
+                                        WebRtc_UWord16* rtcp_port,
+                                        char* ip_address,
+                                        WebRtc_UWord32 ip_address_length) {
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+                 __FUNCTION__);
+    if (external_transport_) {
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: external transport registered", __FUNCTION__);
+      return -1;
+    }
+  }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.IpV6Enabled() &&
+      ip_address_length < UdpTransport::kIpAddressVersion6Length) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: IP address length is too small for IPv6", __FUNCTION__);
+    return -1;
+  } else if (ip_address_length < UdpTransport::kIpAddressVersion4Length) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: IP address length is too small for IPv4", __FUNCTION__);
+    return -1;
+  }
+
+  if (socket_transport_.RemoteSocketInformation(ip_address, *rtp_port,
+                                                *rtcp_port) != 0) {
+    WebRtc_Word32 socket_error = socket_transport_.LastError();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: Error getting source ports. Socket error: %d",
+                 __FUNCTION__, socket_error);
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
 WebRtc_Word32 ViEChannel::RegisterSendTransport(Transport* transport) {
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
                __FUNCTION__);
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.SendSocketsInitialized() ||
+      socket_transport_.ReceiveSocketsInitialized()) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s:  socket transport already initialized", __FUNCTION__);
+    return -1;
+  }
+#endif
+  if (rtp_rtcp_->Sending()) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: Sending", __FUNCTION__);
+    return -1;
+  }
+
   CriticalSectionScoped cs(callback_cs_.get());
   if (external_transport_) {
     WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
@@ -1416,14 +1790,258 @@
 
 WebRtc_Word32 ViEChannel::ReceivedRTPPacket(
     const void* rtp_packet, const WebRtc_Word32 rtp_packet_length) {
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    if (!external_transport_) {
+      return -1;
+    }
+  }
   return vie_receiver_.ReceivedRTPPacket(rtp_packet, rtp_packet_length);
 }
 
 WebRtc_Word32 ViEChannel::ReceivedRTCPPacket(
-    const void* rtcp_packet, const WebRtc_Word32 rtcp_packet_length) {
+  const void* rtcp_packet, const WebRtc_Word32 rtcp_packet_length) {
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    if (!external_transport_) {
+      return -1;
+    }
+  }
   return vie_receiver_.ReceivedRTCPPacket(rtcp_packet, rtcp_packet_length);
 }
 
+WebRtc_Word32 ViEChannel::EnableIPv6() {
+  callback_cs_->Enter();
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s", __FUNCTION__);
+
+  if (external_transport_) {
+    callback_cs_->Leave();
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(engine_id_, channel_id_),
+                 "%s: External transport registered", __FUNCTION__);
+    return -1;
+  }
+  callback_cs_->Leave();
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.IpV6Enabled()) {
+    WEBRTC_TRACE(kTraceWarning, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: IPv6 already enabled", __FUNCTION__);
+    return -1;
+  }
+
+  if (socket_transport_.EnableIpV6() != 0) {
+    WebRtc_Word32 socket_error = socket_transport_.LastError();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: could not enable IPv6. Socket error: %d", __FUNCTION__,
+                 socket_error);
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
+bool ViEChannel::IsIPv6Enabled() {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    if (external_transport_) {
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: External transport registered", __FUNCTION__);
+      return false;
+    }
+  }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  return socket_transport_.IpV6Enabled();
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return false;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::SetSourceFilter(const WebRtc_UWord16 rtp_port,
+                                          const WebRtc_UWord16 rtcp_port,
+                                          const char* ip_address) {
+  callback_cs_->Enter();
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+
+  if (external_transport_) {
+    callback_cs_->Leave();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: External transport registered", __FUNCTION__);
+    return -1;
+  }
+  callback_cs_->Leave();
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.SetFilterIP(ip_address) != 0) {
+    // Logging done in module.
+    return -1;
+  }
+  if (socket_transport_.SetFilterPorts(rtp_port, rtcp_port) != 0) {
+    // Logging done.
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::GetSourceFilter(WebRtc_UWord16* rtp_port,
+                                          WebRtc_UWord16* rtcp_port,
+                                          char* ip_address) const {
+  callback_cs_->Enter();
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+
+  if (external_transport_) {
+    callback_cs_->Leave();
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: External transport registered", __FUNCTION__);
+    return -1;
+  }
+  callback_cs_->Leave();
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.FilterIP(ip_address) != 0) {
+    // Logging done in module.
+    return -1;
+  }
+  if (socket_transport_.FilterPorts(*rtp_port, *rtcp_port) != 0) {
+    // Logging done in module.
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::SetToS(const WebRtc_Word32 DSCP,
+                                 const bool use_set_sockOpt) {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    if (external_transport_) {
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: External transport registered", __FUNCTION__);
+      return -1;
+    }
+  }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.SetToS(DSCP, use_set_sockOpt) != 0) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: Socket error: %d", __FUNCTION__,
+                 socket_transport_.LastError());
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::GetToS(WebRtc_Word32* DSCP,
+                                 bool* use_set_sockOpt) const {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    if (external_transport_) {
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: External transport registered", __FUNCTION__);
+      return -1;
+    }
+  }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.ToS(*DSCP, *use_set_sockOpt) != 0) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: Socket error: %d", __FUNCTION__,
+                 socket_transport_.LastError());
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::SetSendGQoS(const bool enable,
+                                      const WebRtc_Word32 service_type,
+                                      const WebRtc_UWord32 max_bitrate,
+                                      const WebRtc_Word32 overrideDSCP) {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    if (external_transport_) {
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: External transport registered", __FUNCTION__);
+      return -1;
+    }
+  }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.SetQoS(enable, service_type, max_bitrate, overrideDSCP,
+                               false) != 0) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: Socket error: %d", __FUNCTION__,
+                 socket_transport_.LastError());
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
+WebRtc_Word32 ViEChannel::GetSendGQoS(bool* enabled,
+                                      WebRtc_Word32* service_type,
+                                      WebRtc_Word32* overrideDSCP) const {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    if (external_transport_) {
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: External transport registered", __FUNCTION__);
+      return -1;
+    }
+  }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (socket_transport_.QoS(*enabled, *service_type, *overrideDSCP) != 0) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                 "%s: Socket error: %d", __FUNCTION__,
+                 socket_transport_.LastError());
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
 WebRtc_Word32 ViEChannel::SetMTU(WebRtc_UWord16 mtu) {
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
                __FUNCTION__);
@@ -1534,6 +2152,35 @@
   return 0;
 }
 
+WebRtc_Word32 ViEChannel::SendUDPPacket(const WebRtc_Word8* data,
+                                        const WebRtc_UWord32 length,
+                                        WebRtc_Word32& transmitted_bytes,
+                                        bool use_rtcp_socket) {
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+               __FUNCTION__);
+  {
+    CriticalSectionScoped cs(callback_cs_.get());
+    if (external_transport_) {
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_),
+                   "%s: External transport registered", __FUNCTION__);
+      return -1;
+    }
+  }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  transmitted_bytes = socket_transport_.SendRaw(data, length, use_rtcp_socket);
+  if (transmitted_bytes == -1) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(engine_id_, channel_id_), "%s",
+                 __FUNCTION__);
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
+               "%s: not available for external transport", __FUNCTION__);
+  return -1;
+#endif
+}
+
 WebRtc_Word32 ViEChannel::EnableColorEnhancement(bool enable) {
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
                "%s(enable: %d)", __FUNCTION__, enable);
@@ -1747,7 +2394,7 @@
     return -1;
   }
 
-  external_encryption_ = NULL;
+  external_transport_ = NULL;
   vie_receiver_.DeregisterExternalDecryption();
   vie_sender_.DeregisterExternalEncryption();
   WEBRTC_TRACE(kTraceInfo, kTraceVideo, ViEId(engine_id_, channel_id_),
@@ -1868,7 +2515,11 @@
 
   CriticalSectionScoped cs(callback_cs_.get());
   if (networkObserver_) {
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (socket_transport_.Receiving() || external_transport_) {
+#else
     if (external_transport_) {
+#endif
       networkObserver_->PacketTimeout(channel_id_, NoPacket);
       rtp_packet_timeout_ = true;
     }
diff --git a/video_engine/vie_channel.h b/video_engine/vie_channel.h
index 631fb37..fe333aa 100644
--- a/video_engine/vie_channel.h
+++ b/video_engine/vie_channel.h
@@ -15,6 +15,7 @@
 
 #include "modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
 #include "modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "modules/udp_transport/interface/udp_transport.h"
 #include "modules/video_coding/main/interface/video_coding_defines.h"
 #include "system_wrappers/interface/scoped_ptr.h"
 #include "system_wrappers/interface/tick_util.h"
@@ -218,6 +219,27 @@
                                      const WebRtc_UWord32 CSRC,
                                      const bool added);
 
+  WebRtc_Word32 SetLocalReceiver(const WebRtc_UWord16 rtp_port,
+                                 const WebRtc_UWord16 rtcp_port,
+                                 const char* ip_address);
+  WebRtc_Word32 GetLocalReceiver(WebRtc_UWord16* rtp_port,
+                                 WebRtc_UWord16* rtcp_port,
+                                 char* ip_address) const;
+  WebRtc_Word32 SetSendDestination(const char* ip_address,
+                                   const WebRtc_UWord16 rtp_port,
+                                   const WebRtc_UWord16 rtcp_port,
+                                   const WebRtc_UWord16 source_rtp_port,
+                                   const WebRtc_UWord16 source_rtcp_port);
+  WebRtc_Word32 GetSendDestination(char* ip_address,
+                                   WebRtc_UWord16* rtp_port,
+                                   WebRtc_UWord16* rtcp_port,
+                                   WebRtc_UWord16* source_rtp_port,
+                                   WebRtc_UWord16* source_rtcp_port) const;
+  WebRtc_Word32 GetSourceInfo(WebRtc_UWord16* rtp_port,
+                              WebRtc_UWord16* rtcp_port,
+                              char* ip_address,
+                              WebRtc_UWord32 ip_address_length);
+
   WebRtc_Word32 SetRemoteSSRCType(const StreamType usage,
                                   const uint32_t SSRC) const;
 
@@ -226,6 +248,7 @@
   bool Sending();
   WebRtc_Word32 StartReceive();
   WebRtc_Word32 StopReceive();
+  bool Receiving();
 
   WebRtc_Word32 RegisterSendTransport(Transport* transport);
   WebRtc_Word32 DeregisterSendTransport();
@@ -238,6 +261,25 @@
   WebRtc_Word32 ReceivedRTCPPacket(const void* rtcp_packet,
                                    const WebRtc_Word32 rtcp_packet_length);
 
+  WebRtc_Word32 EnableIPv6();
+  bool IsIPv6Enabled();
+  WebRtc_Word32 SetSourceFilter(const WebRtc_UWord16 rtp_port,
+                                const WebRtc_UWord16 rtcp_port,
+                                const char* ip_address);
+  WebRtc_Word32 GetSourceFilter(WebRtc_UWord16* rtp_port,
+                                WebRtc_UWord16* rtcp_port,
+                                char* ip_address) const;
+
+  WebRtc_Word32 SetToS(const WebRtc_Word32 DSCP, const bool use_set_sockOpt);
+  WebRtc_Word32 GetToS(WebRtc_Word32* DSCP, bool* use_set_sockOpt) const;
+  WebRtc_Word32 SetSendGQoS(const bool enable,
+                            const WebRtc_Word32 service_type,
+                            const WebRtc_UWord32 max_bitrate,
+                            const WebRtc_Word32 overrideDSCP);
+  WebRtc_Word32 GetSendGQoS(bool* enabled,
+                            WebRtc_Word32* service_type,
+                            WebRtc_Word32* overrideDSCP) const;
+
   // Sets the maximum transfer unit size for the network link, i.e. including
   // IP, UDP and RTP headers.
   WebRtc_Word32 SetMTU(WebRtc_UWord16 mtu);
@@ -256,6 +298,11 @@
   WebRtc_Word32 SetPeriodicDeadOrAliveStatus(
       const bool enable, const WebRtc_UWord32 sample_time_seconds);
 
+  WebRtc_Word32 SendUDPPacket(const WebRtc_Word8* data,
+                              const WebRtc_UWord32 length,
+                              WebRtc_Word32& transmitted_bytes,
+                              bool use_rtcp_socket);
+
   WebRtc_Word32 EnableColorEnhancement(bool enable);
 
   // Gets the modules used by the channel.
@@ -337,6 +384,9 @@
   scoped_ptr<RtpRtcp> rtp_rtcp_;
   std::list<RtpRtcp*> simulcast_rtp_rtcp_;
   std::list<RtpRtcp*> removed_rtp_rtcp_;
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  UdpTransport& socket_transport_;
+#endif
   VideoCodingModule& vcm_;
   ViEReceiver vie_receiver_;
   ViESender vie_sender_;
diff --git a/video_engine/vie_impl.cc b/video_engine/vie_impl.cc
index 6b1eb43..b8066d7 100644
--- a/video_engine/vie_impl.cc
+++ b/video_engine/vie_impl.cc
@@ -127,12 +127,14 @@
     return false;
   }
 #endif
+#ifdef WEBRTC_VIDEO_ENGINE_NETWORK_API
   ViENetworkImpl* vie_network = vie_impl;
   if (vie_network->GetCount() > 0) {
     WEBRTC_TRACE(kTraceError, kTraceVideo, g_vie_active_instance_counter,
                  "ViENetwork ref count: %d", vie_network->GetCount());
     return false;
   }
+#endif
 #ifdef WEBRTC_VIDEO_ENGINE_RENDER_API
   ViERenderImpl* vie_render = vie_impl;
   if (vie_render->GetCount() > 0) {
diff --git a/video_engine/vie_impl.h b/video_engine/vie_impl.h
index b230fba..ca5d903 100644
--- a/video_engine/vie_impl.h
+++ b/video_engine/vie_impl.h
@@ -31,7 +31,9 @@
 #ifdef WEBRTC_VIDEO_ENGINE_IMAGE_PROCESS_API
 #include "video_engine/vie_image_process_impl.h"
 #endif
+#ifdef WEBRTC_VIDEO_ENGINE_NETWORK_API
 #include "video_engine/vie_network_impl.h"
+#endif
 #ifdef WEBRTC_VIDEO_ENGINE_RENDER_API
 #include "video_engine/vie_render_impl.h"
 #endif
@@ -61,7 +63,9 @@
 #ifdef WEBRTC_VIDEO_ENGINE_IMAGE_PROCESS_API
       , public ViEImageProcessImpl
 #endif
+#ifdef WEBRTC_VIDEO_ENGINE_NETWORK_API
       , public ViENetworkImpl
+#endif
 #ifdef WEBRTC_VIDEO_ENGINE_RENDER_API
       , public ViERenderImpl
 #endif
@@ -90,7 +94,9 @@
 #ifdef WEBRTC_VIDEO_ENGINE_IMAGE_PROCESS_API
         , ViEImageProcessImpl(ViEBaseImpl::shared_data())
 #endif
+#ifdef WEBRTC_VIDEO_ENGINE_NETWORK_API
         , ViENetworkImpl(ViEBaseImpl::shared_data())
+#endif
 #ifdef WEBRTC_VIDEO_ENGINE_RENDER_API
         , ViERenderImpl(ViEBaseImpl::shared_data())
 #endif
diff --git a/video_engine/vie_network_impl.cc b/video_engine/vie_network_impl.cc
index 96c8be5..378d08f 100644
--- a/video_engine/vie_network_impl.cc
+++ b/video_engine/vie_network_impl.cc
@@ -10,6 +10,11 @@
 
 #include "video_engine/vie_network_impl.h"
 
+#include <stdio.h>
+#if (defined(WIN32_) || defined(WIN64_))
+#include <qos.h>
+#endif
+
 #include "engine_configurations.h"  // NOLINT
 #include "system_wrappers/interface/trace.h"
 #include "video_engine/include/vie_errors.h"
@@ -23,6 +28,7 @@
 namespace webrtc {
 
 ViENetwork* ViENetwork::GetInterface(VideoEngine* video_engine) {
+#ifdef WEBRTC_VIDEO_ENGINE_NETWORK_API
   if (!video_engine) {
     return NULL;
   }
@@ -31,6 +37,9 @@
   // Increase ref count.
   (*vie_networkImpl)++;
   return vie_networkImpl;
+#else
+  return NULL;
+#endif
 }
 
 int ViENetworkImpl::Release() {
@@ -62,6 +71,140 @@
                "ViENetworkImpl::~ViENetworkImpl() Dtor");
 }
 
+int ViENetworkImpl::SetLocalReceiver(const int video_channel,
+                                     const uint16_t rtp_port,
+                                     const uint16_t rtcp_port,
+                                     const char* ip_address) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d, rtp_port: %u, rtcp_port: %u, ip_address: %s)",
+               __FUNCTION__, video_channel, rtp_port, rtcp_port, ip_address);
+  if (!shared_data_->Initialized()) {
+    shared_data_->SetLastError(kViENotInitialized);
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
+                 "%s - ViE instance %d not initialized", __FUNCTION__,
+                 shared_data_->instance_id());
+    return -1;
+  }
+
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    // The channel doesn't exists.
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+
+  if (vie_channel->Receiving()) {
+    shared_data_->SetLastError(kViENetworkAlreadyReceiving);
+    return -1;
+  }
+  if (vie_channel->SetLocalReceiver(rtp_port, rtcp_port, ip_address) != 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
+int ViENetworkImpl::GetLocalReceiver(const int video_channel,
+                                     uint16_t& rtp_port,
+                                     uint16_t& rtcp_port,
+                                     char* ip_address) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d)", __FUNCTION__, video_channel);
+
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->GetLocalReceiver(&rtp_port, &rtcp_port, ip_address) != 0) {
+    shared_data_->SetLastError(kViENetworkLocalReceiverNotSet);
+    return -1;
+  }
+  return 0;
+}
+
+int ViENetworkImpl::SetSendDestination(const int video_channel,
+                                       const char* ip_address,
+                                       const uint16_t rtp_port,
+                                       const uint16_t rtcp_port,
+                                       const uint16_t source_rtp_port,
+                                       const uint16_t source_rtcp_port) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d, ip_address: %s, rtp_port: %u, rtcp_port: %u, "
+               "sourceRtpPort: %u, source_rtcp_port: %u)",
+               __FUNCTION__, video_channel, ip_address, rtp_port, rtcp_port,
+               source_rtp_port, source_rtcp_port);
+  if (!shared_data_->Initialized()) {
+    shared_data_->SetLastError(kViENotInitialized);
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
+                 "%s - ViE instance %d not initialized", __FUNCTION__,
+                 shared_data_->instance_id());
+    return -1;
+  }
+
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "%s Channel doesn't exist", __FUNCTION__);
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->Sending()) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "%s Channel already sending.", __FUNCTION__);
+    shared_data_->SetLastError(kViENetworkAlreadySending);
+    return -1;
+  }
+  if (vie_channel->SetSendDestination(ip_address, rtp_port, rtcp_port,
+                                          source_rtp_port,
+                                          source_rtcp_port) != 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
+int ViENetworkImpl::GetSendDestination(const int video_channel,
+                                       char* ip_address,
+                                       uint16_t& rtp_port,
+                                       uint16_t& rtcp_port,
+                                       uint16_t& source_rtp_port,
+                                       uint16_t& source_rtcp_port) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d)", __FUNCTION__, video_channel);
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->GetSendDestination(ip_address, &rtp_port, &rtcp_port,
+                                      &source_rtp_port,
+                                      &source_rtcp_port) != 0) {
+    shared_data_->SetLastError(kViENetworkDestinationNotSet);
+    return -1;
+  }
+  return 0;
+}
+
 int ViENetworkImpl::RegisterSendTransport(const int video_channel,
                                           Transport& transport) {
   WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
@@ -175,6 +318,340 @@
   return vie_channel->ReceivedRTCPPacket(data, length);
 }
 
+int ViENetworkImpl::GetSourceInfo(const int video_channel,
+                                  uint16_t& rtp_port,
+                                  uint16_t& rtcp_port, char* ip_address,
+                                  unsigned int ip_address_length) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d)", __FUNCTION__, video_channel);
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->GetSourceInfo(&rtp_port, &rtcp_port, ip_address,
+                                 ip_address_length) != 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
+int ViENetworkImpl::GetLocalIP(char ip_address[64], bool ipv6) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
+               "%s( ip_address, ipV6: %d)", __FUNCTION__, ipv6);
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  if (!shared_data_->Initialized()) {
+    shared_data_->SetLastError(kViENotInitialized);
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
+                 "%s - ViE instance %d not initialized", __FUNCTION__,
+                 shared_data_->instance_id());
+    return -1;
+  }
+
+  if (!ip_address) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
+                 "%s: No argument", __FUNCTION__);
+    shared_data_->SetLastError(kViENetworkInvalidArgument);
+    return -1;
+  }
+
+  WebRtc_UWord8 num_socket_threads = 1;
+  UdpTransport* socket_transport = UdpTransport::Create(
+      ViEModuleId(shared_data_->instance_id(), -1), num_socket_threads);
+
+  if (!socket_transport) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
+                 "%s: Could not create socket module", __FUNCTION__);
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+
+  char local_ip_address[64];
+  if (ipv6) {
+    char local_ip[16];
+    if (socket_transport->LocalHostAddressIPV6(local_ip) != 0) {
+      UdpTransport::Destroy(socket_transport);
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
+                   "%s: Could not get local IP", __FUNCTION__);
+      shared_data_->SetLastError(kViENetworkUnknownError);
+      return -1;
+    }
+    // Convert 128-bit address to character string (a:b:c:d:e:f:g:h).
+    // TODO(mflodman) Change sprintf.
+    sprintf(local_ip_address,  // NOLINT
+            "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:"
+            "%.2x%.2x",
+            local_ip[0], local_ip[1], local_ip[2], local_ip[3], local_ip[4],
+            local_ip[5], local_ip[6], local_ip[7], local_ip[8], local_ip[9],
+            local_ip[10], local_ip[11], local_ip[12], local_ip[13],
+            local_ip[14], local_ip[15]);
+  } else {
+    WebRtc_UWord32 local_ip = 0;
+    if (socket_transport->LocalHostAddress(local_ip) != 0) {
+      UdpTransport::Destroy(socket_transport);
+      WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
+                   "%s: Could not get local IP", __FUNCTION__);
+      shared_data_->SetLastError(kViENetworkUnknownError);
+      return -1;
+    }
+    // Convert 32-bit address to character string (x.y.z.w).
+    // TODO(mflodman) Change sprintf.
+    sprintf(local_ip_address, "%d.%d.%d.%d",  // NOLINT
+            static_cast<int>((local_ip >> 24) & 0x0ff),
+            static_cast<int>((local_ip >> 16) & 0x0ff),
+            static_cast<int>((local_ip >> 8) & 0x0ff),
+            static_cast<int>(local_ip & 0x0ff));
+  }
+  strncpy(ip_address, local_ip_address, sizeof(local_ip_address));
+  UdpTransport::Destroy(socket_transport);
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(shared_data_->instance_id()),
+               "%s: local ip = %s", __FUNCTION__, local_ip_address);
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceStateInfo, kTraceVideo, ViEId(shared_data_->instance_id()),
+               "%s: not available for external transport", __FUNCTION__);
+
+  return -1;
+#endif
+}
+
+int ViENetworkImpl::EnableIPv6(int video_channel) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d)", __FUNCTION__, video_channel);
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->EnableIPv6() != 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
+bool ViENetworkImpl::IsIPv6Enabled(int video_channel) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d)", __FUNCTION__, video_channel);
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return false;
+  }
+  return vie_channel->IsIPv6Enabled();
+}
+
+int ViENetworkImpl::SetSourceFilter(const int video_channel,
+                                    const uint16_t rtp_port,
+                                    const uint16_t rtcp_port,
+                                    const char* ip_address) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d, rtp_port: %u, rtcp_port: %u, ip_address: %s)",
+               __FUNCTION__, video_channel, rtp_port, rtcp_port, ip_address);
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->SetSourceFilter(rtp_port, rtcp_port, ip_address) != 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
+int ViENetworkImpl::GetSourceFilter(const int video_channel,
+                                    uint16_t& rtp_port,
+                                    uint16_t& rtcp_port,
+                                    char* ip_address) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d)", __FUNCTION__, video_channel);
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->GetSourceFilter(&rtp_port, &rtcp_port, ip_address) != 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
+int ViENetworkImpl::SetSendToS(const int video_channel, const int DSCP,
+                               const bool use_set_sockOpt = false) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d, DSCP: %d, use_set_sockOpt: %d)", __FUNCTION__,
+               video_channel, DSCP, use_set_sockOpt);
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+
+#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
+  WEBRTC_TRACE(kTraceInfo, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "   force use_set_sockopt=true since there is no alternative"
+               " implementation");
+  if (vie_channel->SetToS(DSCP, true) != 0) {
+#else
+  if (vie_channel->SetToS(DSCP, use_set_sockOpt) != 0) {
+#endif
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
+int ViENetworkImpl::GetSendToS(const int video_channel,
+                               int& DSCP,  // NOLINT
+                               bool& use_set_sockOpt) {  // NOLINT
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d)", __FUNCTION__, video_channel);
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->GetToS(&DSCP, &use_set_sockOpt) != 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
+int ViENetworkImpl::SetSendGQoS(const int video_channel, const bool enable,
+                                const int service_type,
+                                const int overrideDSCP) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d, enable: %d, service_type: %d, "
+               "overrideDSCP: %d)", __FUNCTION__, video_channel, enable,
+               service_type, overrideDSCP);
+  if (!shared_data_->Initialized()) {
+    shared_data_->SetLastError(kViENotInitialized);
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
+                 "%s - ViE instance %d not initialized", __FUNCTION__,
+                 shared_data_->instance_id());
+    return -1;
+  }
+
+#if (defined(WIN32_) || defined(WIN64_))
+  // Sanity check. We might crash if testing and relying on an OS socket error.
+  if (enable &&
+      (service_type != SERVICETYPE_BESTEFFORT) &&
+      (service_type != SERVICETYPE_CONTROLLEDLOAD) &&
+      (service_type != SERVICETYPE_GUARANTEED) &&
+      (service_type != SERVICETYPE_QUALITATIVE)) {
+    WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "%s: service type %d not supported", __FUNCTION__,
+                 video_channel, service_type);
+    shared_data_->SetLastError(kViENetworkServiceTypeNotSupported);
+    return -1;
+  }
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
+  if (!vie_encoder) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  VideoCodec video_codec;
+  if (vie_encoder->GetEncoder(video_codec) != 0) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "%s: Could not get max bitrate for the channel",
+                 __FUNCTION__);
+    shared_data_->SetLastError(kViENetworkSendCodecNotSet);
+    return -1;
+  }
+  if (vie_channel->SetSendGQoS(enable, service_type, video_codec.maxBitrate,
+                               overrideDSCP) != 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+#else
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s: Not supported", __FUNCTION__);
+  shared_data_->SetLastError(kViENetworkNotSupported);
+  return -1;
+#endif
+}
+
+int ViENetworkImpl::GetSendGQoS(const int video_channel,
+                                bool& enabled,  // NOLINT
+                                int& service_type,  // NOLINT
+                                int& overrideDSCP) {  // NOLINT
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d)", __FUNCTION__, video_channel);
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->GetSendGQoS(&enabled, &service_type, &overrideDSCP) != 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
 int ViENetworkImpl::SetMTU(int video_channel, unsigned int mtu) {
   WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
                ViEId(shared_data_->instance_id(), video_channel),
@@ -289,4 +766,38 @@
   return 0;
 }
 
+int ViENetworkImpl::SendUDPPacket(const int video_channel, const void* data,
+                                  const unsigned int length,
+                                  int& transmitted_bytes,
+                                  bool use_rtcp_socket = false) {
+  WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
+               ViEId(shared_data_->instance_id(), video_channel),
+               "%s(channel: %d, data: -, length: %d, transmitter_bytes: -, "
+               "useRtcpSocket: %d)", __FUNCTION__, video_channel, length,
+               use_rtcp_socket);
+  if (!shared_data_->Initialized()) {
+    shared_data_->SetLastError(kViENotInitialized);
+    WEBRTC_TRACE(kTraceError, kTraceVideo, ViEId(shared_data_->instance_id()),
+                 "%s - ViE instance %d not initialized", __FUNCTION__,
+                 shared_data_->instance_id());
+    return -1;
+  }
+  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
+  ViEChannel* vie_channel = cs.Channel(video_channel);
+  if (!vie_channel) {
+    WEBRTC_TRACE(kTraceError, kTraceVideo,
+                 ViEId(shared_data_->instance_id(), video_channel),
+                 "Channel doesn't exist");
+    shared_data_->SetLastError(kViENetworkInvalidChannelId);
+    return -1;
+  }
+  if (vie_channel->SendUDPPacket((const WebRtc_Word8*) data, length,
+                                     (WebRtc_Word32&) transmitted_bytes,
+                                     use_rtcp_socket) < 0) {
+    shared_data_->SetLastError(kViENetworkUnknownError);
+    return -1;
+  }
+  return 0;
+}
+
 }  // namespace webrtc
diff --git a/video_engine/vie_network_impl.h b/video_engine/vie_network_impl.h
index 6e992eb..56832df 100644
--- a/video_engine/vie_network_impl.h
+++ b/video_engine/vie_network_impl.h
@@ -25,6 +25,26 @@
  public:
   // Implements ViENetwork.
   virtual int Release();
+  virtual int SetLocalReceiver(const int video_channel,
+                               const uint16_t rtp_port,
+                               const uint16_t rtcp_port,
+                               const char* ip_address);
+  virtual int GetLocalReceiver(const int video_channel,
+                               uint16_t& rtp_port,
+                               uint16_t& rtcp_port,
+                               char* ip_address);
+  virtual int SetSendDestination(const int video_channel,
+                                 const char* ip_address,
+                                 const uint16_t rtp_port,
+                                 const uint16_t rtcp_port,
+                                 const uint16_t source_rtp_port,
+                                 const uint16_t source_rtcp_port);
+  virtual int GetSendDestination(const int video_channel,
+                                 char* ip_address,
+                                 uint16_t& rtp_port,
+                                 uint16_t& rtcp_port,
+                                 uint16_t& source_rtp_port,
+                                 uint16_t& source_rtcp_port);
   virtual int RegisterSendTransport(const int video_channel,
                                     Transport& transport);
   virtual int DeregisterSendTransport(const int video_channel);
@@ -34,6 +54,36 @@
   virtual int ReceivedRTCPPacket(const int video_channel,
                                  const void* data,
                                  const int length);
+  virtual int GetSourceInfo(const int video_channel,
+                            uint16_t& rtp_port,
+                            uint16_t& rtcp_port,
+                            char* ip_address,
+                            unsigned int ip_address_length);
+  virtual int GetLocalIP(char ip_address[64], bool ipv6);
+  virtual int EnableIPv6(int video_channel);
+  virtual bool IsIPv6Enabled(int video_channel);
+  virtual int SetSourceFilter(const int video_channel,
+                              const uint16_t rtp_port,
+                              const uint16_t rtcp_port,
+                              const char* ip_address);
+  virtual int GetSourceFilter(const int video_channel,
+                              uint16_t& rtp_port,
+                              uint16_t& rtcp_port,
+                              char* ip_address);
+  virtual int SetSendToS(const int video_channel,
+                         const int DSCP,
+                         const bool use_set_sockOpt);
+  virtual int GetSendToS(const int video_channel,
+                         int& DSCP,
+                         bool& use_set_sockOpt);
+  virtual int SetSendGQoS(const int video_channel,
+                          const bool enable,
+                          const int service_type,
+                          const int overrideDSCP);
+  virtual int GetSendGQoS(const int video_channel,
+                          bool& enabled,
+                          int& service_type,
+                          int& overrideDSCP);
   virtual int SetMTU(int video_channel, unsigned int mtu);
   virtual int SetPacketTimeoutNotification(const int video_channel,
                                            bool enable,
@@ -45,6 +95,11 @@
       const int video_channel,
       const bool enable,
       const unsigned int sample_time_seconds);
+  virtual int SendUDPPacket(const int video_channel,
+                            const void* data,
+                            const unsigned int length,
+                            int& transmitted_bytes,
+                            bool use_rtcp_socket);
 
  protected:
   explicit ViENetworkImpl(ViESharedData* shared_data);
diff --git a/video_engine/vie_receiver.cc b/video_engine/vie_receiver.cc
index 57c9d16..43aa566 100644
--- a/video_engine/vie_receiver.cc
+++ b/video_engine/vie_receiver.cc
@@ -87,6 +87,20 @@
   }
 }
 
+void ViEReceiver::IncomingRTPPacket(const WebRtc_Word8* rtp_packet,
+                                    const WebRtc_Word32 rtp_packet_length,
+                                    const char* from_ip,
+                                    const WebRtc_UWord16 from_port) {
+  InsertRTPPacket(rtp_packet, rtp_packet_length);
+}
+
+void ViEReceiver::IncomingRTCPPacket(const WebRtc_Word8* rtcp_packet,
+                                     const WebRtc_Word32 rtcp_packet_length,
+                                     const char* from_ip,
+                                     const WebRtc_UWord16 from_port) {
+  InsertRTCPPacket(rtcp_packet, rtcp_packet_length);
+}
+
 int ViEReceiver::ReceivedRTPPacket(const void* rtp_packet,
                                    int rtp_packet_length) {
   if (!receiving_) {
diff --git a/video_engine/vie_receiver.h b/video_engine/vie_receiver.h
index dda2f29..4f43fc9 100644
--- a/video_engine/vie_receiver.h
+++ b/video_engine/vie_receiver.h
@@ -15,6 +15,7 @@
 
 #include "engine_configurations.h"  // NOLINT
 #include "modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
+#include "modules/udp_transport/interface/udp_transport.h"
 #include "system_wrappers/interface/scoped_ptr.h"
 #include "typedefs.h"  // NOLINT
 #include "video_engine/vie_defines.h"
@@ -28,7 +29,7 @@
 class RtpRtcp;
 class VideoCodingModule;
 
-class ViEReceiver : public RtpData {
+class ViEReceiver : public UdpTransportData, public RtpData {
  public:
   ViEReceiver(const int32_t channel_id, VideoCodingModule* module_vcm,
               RemoteBitrateEstimator* remote_bitrate_estimator);
@@ -47,6 +48,16 @@
   int StartRTPDump(const char file_nameUTF8[1024]);
   int StopRTPDump();
 
+  // Implements UdpTransportData.
+  virtual void IncomingRTPPacket(const WebRtc_Word8* rtp_packet,
+                                 const WebRtc_Word32 rtp_packet_length,
+                                 const char* from_ip,
+                                 const WebRtc_UWord16 from_port);
+  virtual void IncomingRTCPPacket(const WebRtc_Word8* rtcp_packet,
+                                  const WebRtc_Word32 rtcp_packet_length,
+                                  const char* from_ip,
+                                  const WebRtc_UWord16 from_port);
+
   // Receives packets from external transport.
   int ReceivedRTPPacket(const void* rtp_packet, int rtp_packet_length);
   int ReceivedRTCPPacket(const void* rtcp_packet, int rtcp_packet_length);
diff --git a/voice_engine/channel.cc b/voice_engine/channel.cc
index 7691bf0..1eabee8 100644
--- a/voice_engine/channel.cc
+++ b/voice_engine/channel.cc
@@ -332,6 +332,163 @@
 }
 
 void
+Channel::IncomingRTPPacket(const WebRtc_Word8* incomingRtpPacket,
+                           const WebRtc_Word32 rtpPacketLength,
+                           const char* fromIP,
+                           const WebRtc_UWord16 fromPort)
+{
+    WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::IncomingRTPPacket(rtpPacketLength=%d,"
+                 " fromIP=%s, fromPort=%u)",
+                 rtpPacketLength, fromIP, fromPort);
+
+    // Store playout timestamp for the received RTP packet
+    // to be used for upcoming delay estimations
+    WebRtc_UWord32 playoutTimestamp(0);
+    if (GetPlayoutTimeStamp(playoutTimestamp) == 0)
+    {
+        _playoutTimeStampRTP = playoutTimestamp;
+    }
+
+    WebRtc_UWord8* rtpBufferPtr = (WebRtc_UWord8*)incomingRtpPacket;
+    WebRtc_Word32 rtpBufferLength = rtpPacketLength;
+
+    // SRTP or External decryption
+    if (_decrypting)
+    {
+        CriticalSectionScoped cs(&_callbackCritSect);
+
+        if (_encryptionPtr)
+        {
+            if (!_decryptionRTPBufferPtr)
+            {
+                // Allocate memory for decryption buffer one time only
+                _decryptionRTPBufferPtr =
+                    new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes];
+            }
+
+            // Perform decryption (SRTP or external)
+            WebRtc_Word32 decryptedBufferLength = 0;
+            _encryptionPtr->decrypt(_channelId,
+                                    rtpBufferPtr,
+                                    _decryptionRTPBufferPtr,
+                                    rtpBufferLength,
+                                    (int*)&decryptedBufferLength);
+            if (decryptedBufferLength <= 0)
+            {
+                _engineStatisticsPtr->SetLastError(
+                    VE_DECRYPTION_FAILED, kTraceError,
+                    "Channel::IncomingRTPPacket() decryption failed");
+                return;
+            }
+
+            // Replace default data buffer with decrypted buffer
+            rtpBufferPtr = _decryptionRTPBufferPtr;
+            rtpBufferLength = decryptedBufferLength;
+        }
+    }
+
+    // Dump the RTP packet to a file (if RTP dump is enabled).
+    if (_rtpDumpIn.DumpPacket(rtpBufferPtr,
+                              (WebRtc_UWord16)rtpBufferLength) == -1)
+    {
+        WEBRTC_TRACE(kTraceWarning, kTraceVoice,
+                     VoEId(_instanceId,_channelId),
+                     "Channel::SendPacket() RTP dump to input file failed");
+    }
+
+    // Deliver RTP packet to RTP/RTCP module for parsing
+    // The packet will be pushed back to the channel thru the
+    // OnReceivedPayloadData callback so we don't push it to the ACM here
+    if (_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)rtpBufferPtr,
+                                      (WebRtc_UWord16)rtpBufferLength) == -1)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
+            "Channel::IncomingRTPPacket() RTP packet is invalid");
+        return;
+    }
+}
+
+void
+Channel::IncomingRTCPPacket(const WebRtc_Word8* incomingRtcpPacket,
+                            const WebRtc_Word32 rtcpPacketLength,
+                            const char* fromIP,
+                            const WebRtc_UWord16 fromPort)
+{
+    WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::IncomingRTCPPacket(rtcpPacketLength=%d, fromIP=%s,"
+                 " fromPort=%u)",
+                 rtcpPacketLength, fromIP, fromPort);
+
+    // Temporary buffer pointer and size for decryption
+    WebRtc_UWord8* rtcpBufferPtr = (WebRtc_UWord8*)incomingRtcpPacket;
+    WebRtc_Word32 rtcpBufferLength = rtcpPacketLength;
+
+    // Store playout timestamp for the received RTCP packet
+    // which will be read by the GetRemoteRTCPData API
+    WebRtc_UWord32 playoutTimestamp(0);
+    if (GetPlayoutTimeStamp(playoutTimestamp) == 0)
+    {
+        _playoutTimeStampRTCP = playoutTimestamp;
+    }
+
+    // SRTP or External decryption
+    if (_decrypting)
+    {
+        CriticalSectionScoped cs(&_callbackCritSect);
+
+        if (_encryptionPtr)
+        {
+            if (!_decryptionRTCPBufferPtr)
+            {
+                // Allocate memory for decryption buffer one time only
+                _decryptionRTCPBufferPtr =
+                    new WebRtc_UWord8[kVoiceEngineMaxIpPacketSizeBytes];
+            }
+
+            // Perform decryption (SRTP or external).
+            WebRtc_Word32 decryptedBufferLength = 0;
+            _encryptionPtr->decrypt_rtcp(_channelId,
+                                         rtcpBufferPtr,
+                                         _decryptionRTCPBufferPtr,
+                                         rtcpBufferLength,
+                                         (int*)&decryptedBufferLength);
+            if (decryptedBufferLength <= 0)
+            {
+                _engineStatisticsPtr->SetLastError(
+                    VE_DECRYPTION_FAILED, kTraceError,
+                    "Channel::IncomingRTCPPacket() decryption failed");
+                return;
+            }
+
+            // Replace default data buffer with decrypted buffer
+            rtcpBufferPtr = _decryptionRTCPBufferPtr;
+            rtcpBufferLength = decryptedBufferLength;
+        }
+    }
+
+    // Dump the RTCP packet to a file (if RTP dump is enabled).
+    if (_rtpDumpIn.DumpPacket(rtcpBufferPtr,
+                              (WebRtc_UWord16)rtcpBufferLength) == -1)
+    {
+        WEBRTC_TRACE(kTraceWarning, kTraceVoice,
+                     VoEId(_instanceId,_channelId),
+                     "Channel::SendPacket() RTCP dump to input file failed");
+    }
+
+    // Deliver RTCP packet to RTP/RTCP module for parsing
+    if (_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)rtcpBufferPtr,
+                                      (WebRtc_UWord16)rtcpBufferLength) == -1)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
+            "Channel::IncomingRTPPacket() RTCP packet is invalid");
+        return;
+    }
+}
+
+void
 Channel::OnPlayTelephoneEvent(const WebRtc_Word32 id,
                               const WebRtc_UWord8 event,
                               const WebRtc_UWord16 lengthMs,
@@ -871,6 +1028,11 @@
     _channelId(channelId),
     _audioCodingModule(*AudioCodingModule::Create(
         VoEModuleId(instanceId, channelId))),
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+     _numSocketThreads(KNumSocketThreads),
+    _socketTransportModule(*UdpTransport::Create(
+        VoEModuleId(instanceId, channelId), _numSocketThreads)),
+#endif
 #ifdef WEBRTC_SRTP
     _srtpModule(*SrtpModule::CreateSrtpModule(VoEModuleId(instanceId,
                                                           channelId))),
@@ -999,6 +1161,18 @@
         DeRegisterExternalMediaProcessing(kRecordingPerChannel);
     }
     StopSend();
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    StopReceiving();
+    // De-register packet callback to ensure we're not in a callback when
+    // deleting channel state, avoids race condition and deadlock.
+    if (_socketTransportModule.InitializeReceiveSockets(NULL, 0, NULL, NULL, 0)
+            != 0)
+    {
+        WEBRTC_TRACE(kTraceWarning, kTraceVoice,
+                     VoEId(_instanceId, _channelId),
+                     "~Channel() failed to de-register receive callback");
+    }
+#endif
     StopPlayout();
 
     {
@@ -1045,6 +1219,15 @@
                      " (Audio coding module)");
     }
     // De-register modules in process thread
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (_moduleProcessThreadPtr->DeRegisterModule(&_socketTransportModule)
+            == -1)
+    {
+        WEBRTC_TRACE(kTraceInfo, kTraceVoice,
+                     VoEId(_instanceId,_channelId),
+                     "~Channel() failed to deregister socket module");
+    }
+#endif
     if (_moduleProcessThreadPtr->DeRegisterModule(_rtpRtcpModule.get()) == -1)
     {
         WEBRTC_TRACE(kTraceInfo, kTraceVoice,
@@ -1053,6 +1236,10 @@
     }
 
     // Destroy modules
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    UdpTransport::Destroy(
+        &_socketTransportModule);
+#endif
     AudioCodingModule::Destroy(&_audioCodingModule);
 #ifdef WEBRTC_SRTP
     SrtpModule::DestroySrtpModule(&_srtpModule);
@@ -1097,7 +1284,12 @@
 
     const bool processThreadFail =
         ((_moduleProcessThreadPtr->RegisterModule(_rtpRtcpModule.get()) != 0) ||
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+        (_moduleProcessThreadPtr->RegisterModule(
+                &_socketTransportModule) != 0));
+#else
         false);
+#endif
     if (processThreadFail)
     {
         _engineStatisticsPtr->SetLastError(
@@ -1231,6 +1423,17 @@
         }
 #endif
     }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    // Ensure that the WebRtcSocketTransport implementation is used as
+    // Transport on the sending side
+    {
+        // A lock is needed here since users can call
+        // RegisterExternalTransport() at the same time.
+        CriticalSectionScoped cs(&_callbackCritSect);
+        _transportPtr = &_socketTransportModule;
+    }
+#endif
+
     // Initialize the far end AP module
     // Using 8 kHz as initial Fs, the same as in transmission. Might be
     // changed at the first receiving audio.
@@ -1459,6 +1662,25 @@
     // If external transport is used, we will only initialize/set the variables
     // after this section, since we are not using the WebRtc transport but
     // still need to keep track of e.g. if we are receiving.
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_externalTransport)
+    {
+        if (!_socketTransportModule.ReceiveSocketsInitialized())
+        {
+            _engineStatisticsPtr->SetLastError(
+                VE_SOCKETS_NOT_INITED, kTraceError,
+                "StartReceive() must set local receiver first");
+            return -1;
+        }
+        if (_socketTransportModule.StartReceiving(KNumberOfSocketBuffers) != 0)
+        {
+            _engineStatisticsPtr->SetLastError(
+                VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError,
+                "StartReceiving() failed to start receiving");
+            return -1;
+        }
+    }
+#endif
     _receiving = true;
     _numberOfDiscardedPackets = 0;
     return 0;
@@ -1473,6 +1695,20 @@
     {
         return 0;
     }
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_externalTransport &&
+        _socketTransportModule.ReceiveSocketsInitialized())
+    {
+        if (_socketTransportModule.StopReceiving() != 0)
+        {
+            _engineStatisticsPtr->SetLastError(
+                VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError,
+                "StopReceiving() failed to stop receiving.");
+            return -1;
+        }
+    }
+#endif
     // Recover DTMF detection status.
     WebRtc_Word32 ret = _rtpRtcpModule->SetTelephoneEventForwardToDecoder(true);
     if (ret != 0) {
@@ -1485,6 +1721,310 @@
     return 0;
 }
 
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+WebRtc_Word32
+Channel::SetLocalReceiver(const WebRtc_UWord16 rtpPort,
+                          const WebRtc_UWord16 rtcpPort,
+                          const char ipAddr[64],
+                          const char multicastIpAddr[64])
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::SetLocalReceiver()");
+
+    if (_externalTransport)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "SetLocalReceiver() conflict with external transport");
+        return -1;
+    }
+
+    if (_sending)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_ALREADY_SENDING, kTraceError,
+            "SetLocalReceiver() already sending");
+        return -1;
+    }
+    if (_receiving)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_ALREADY_LISTENING, kTraceError,
+            "SetLocalReceiver() already receiving");
+        return -1;
+    }
+
+    if (_socketTransportModule.InitializeReceiveSockets(this,
+                                                        rtpPort,
+                                                        ipAddr,
+                                                        multicastIpAddr,
+                                                        rtcpPort) != 0)
+    {
+        UdpTransport::ErrorCode lastSockError(
+            _socketTransportModule.LastError());
+        switch (lastSockError)
+        {
+        case UdpTransport::kIpAddressInvalid:
+            _engineStatisticsPtr->SetLastError(
+                VE_INVALID_IP_ADDRESS, kTraceError,
+                "SetLocalReceiver() invalid IP address");
+            break;
+        case UdpTransport::kSocketInvalid:
+            _engineStatisticsPtr->SetLastError(
+                VE_SOCKET_ERROR, kTraceError,
+                "SetLocalReceiver() invalid socket");
+            break;
+        case UdpTransport::kPortInvalid:
+            _engineStatisticsPtr->SetLastError(
+                VE_INVALID_PORT_NMBR, kTraceError,
+                "SetLocalReceiver() invalid port");
+            break;
+        case UdpTransport::kFailedToBindPort:
+            _engineStatisticsPtr->SetLastError(
+                VE_BINDING_SOCKET_TO_LOCAL_ADDRESS_FAILED, kTraceError,
+                "SetLocalReceiver() binding failed");
+            break;
+        default:
+            _engineStatisticsPtr->SetLastError(
+                VE_SOCKET_ERROR, kTraceError,
+                "SetLocalReceiver() undefined socket error");
+            break;
+        }
+        return -1;
+    }
+    return 0;
+}
+#endif
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+WebRtc_Word32
+Channel::GetLocalReceiver(int& port, int& RTCPport, char ipAddr[64])
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::GetLocalReceiver()");
+
+    if (_externalTransport)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "SetLocalReceiver() conflict with external transport");
+        return -1;
+    }
+
+    char ipAddrTmp[UdpTransport::kIpAddressVersion6Length] = {0};
+    WebRtc_UWord16 rtpPort(0);
+    WebRtc_UWord16 rtcpPort(0);
+    char multicastIpAddr[UdpTransport::kIpAddressVersion6Length] = {0};
+
+    // Acquire socket information from the socket module
+    if (_socketTransportModule.ReceiveSocketInformation(ipAddrTmp,
+                                                        rtpPort,
+                                                        rtcpPort,
+                                                        multicastIpAddr) != 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_CANNOT_GET_SOCKET_INFO, kTraceError,
+            "GetLocalReceiver() unable to retrieve socket information");
+        return -1;
+    }
+
+    // Deliver valid results to the user
+    port = static_cast<int> (rtpPort);
+    RTCPport = static_cast<int> (rtcpPort);
+    if (ipAddr != NULL)
+    {
+        strcpy(ipAddr, ipAddrTmp);
+    }
+    return 0;
+}
+#endif
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+WebRtc_Word32
+Channel::SetSendDestination(const WebRtc_UWord16 rtpPort,
+                            const char ipAddr[64],
+                            const int sourcePort,
+                            const WebRtc_UWord16 rtcpPort)
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::SetSendDestination()");
+
+    if (_externalTransport)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "SetSendDestination() conflict with external transport");
+        return -1;
+    }
+
+    // Initialize ports and IP address for the remote (destination) side.
+    // By default, the sockets used for receiving are used for transmission as
+    // well, hence the source ports for outgoing packets are the same as the
+    // receiving ports specified in SetLocalReceiver.
+    // If an extra send socket has been created, it will be utilized until a
+    // new source port is specified or until the channel has been deleted and
+    // recreated. If no socket exists, sockets will be created when the first
+    // RTP and RTCP packets shall be transmitted (see e.g.
+    // UdpTransportImpl::SendPacket()).
+    //
+    // NOTE: this function does not require that sockets exists; all it does is
+    // to build send structures to be used with the sockets when they exist.
+    // It is therefore possible to call this method before SetLocalReceiver.
+    // However, sockets must exist if a multi-cast address is given as input.
+
+    // Build send structures and enable QoS (if enabled and supported)
+    if (_socketTransportModule.InitializeSendSockets(
+        ipAddr, rtpPort, rtcpPort) != UdpTransport::kNoSocketError)
+    {
+        UdpTransport::ErrorCode lastSockError(
+            _socketTransportModule.LastError());
+        switch (lastSockError)
+        {
+        case UdpTransport::kIpAddressInvalid:
+            _engineStatisticsPtr->SetLastError(
+                VE_INVALID_IP_ADDRESS, kTraceError,
+                "SetSendDestination() invalid IP address 1");
+            break;
+        case UdpTransport::kSocketInvalid:
+            _engineStatisticsPtr->SetLastError(
+                VE_SOCKET_ERROR, kTraceError,
+                "SetSendDestination() invalid socket 1");
+            break;
+        case UdpTransport::kQosError:
+            _engineStatisticsPtr->SetLastError(
+                VE_GQOS_ERROR, kTraceError,
+                "SetSendDestination() failed to set QoS");
+            break;
+        case UdpTransport::kMulticastAddressInvalid:
+            _engineStatisticsPtr->SetLastError(
+                VE_INVALID_MULTICAST_ADDRESS, kTraceError,
+                "SetSendDestination() invalid multicast address");
+            break;
+        default:
+            _engineStatisticsPtr->SetLastError(
+                VE_SOCKET_ERROR, kTraceError,
+                "SetSendDestination() undefined socket error 1");
+            break;
+        }
+        return -1;
+    }
+
+    // Check if the user has specified a non-default source port different from
+    // the local receive port.
+    // If so, an extra local socket will be created unless the source port is
+    // not unique.
+    if (sourcePort != kVoEDefault)
+    {
+        WebRtc_UWord16 receiverRtpPort(0);
+        WebRtc_UWord16 rtcpNA(0);
+        if (_socketTransportModule.ReceiveSocketInformation(NULL,
+                                                            receiverRtpPort,
+                                                            rtcpNA,
+                                                            NULL) != 0)
+        {
+            _engineStatisticsPtr->SetLastError(
+                VE_CANNOT_GET_SOCKET_INFO, kTraceError,
+                "SetSendDestination() failed to retrieve socket information");
+            return -1;
+        }
+
+        WebRtc_UWord16 sourcePortUW16 =
+                static_cast<WebRtc_UWord16> (sourcePort);
+
+        // An extra socket will only be created if the specified source port
+        // differs from the local receive port.
+        if (sourcePortUW16 != receiverRtpPort)
+        {
+            // Initialize extra local socket to get a different source port
+            // than the local
+            // receiver port. Always use default source for RTCP.
+            // Note that, this calls UdpTransport::CloseSendSockets().
+            if (_socketTransportModule.InitializeSourcePorts(
+                sourcePortUW16,
+                sourcePortUW16+1) != 0)
+            {
+                UdpTransport::ErrorCode lastSockError(
+                    _socketTransportModule.LastError());
+                switch (lastSockError)
+                {
+                case UdpTransport::kIpAddressInvalid:
+                    _engineStatisticsPtr->SetLastError(
+                        VE_INVALID_IP_ADDRESS, kTraceError,
+                        "SetSendDestination() invalid IP address 2");
+                    break;
+                case UdpTransport::kSocketInvalid:
+                    _engineStatisticsPtr->SetLastError(
+                        VE_SOCKET_ERROR, kTraceError,
+                        "SetSendDestination() invalid socket 2");
+                    break;
+                default:
+                    _engineStatisticsPtr->SetLastError(
+                        VE_SOCKET_ERROR, kTraceError,
+                        "SetSendDestination() undefined socket error 2");
+                    break;
+                }
+                return -1;
+            }
+            WEBRTC_TRACE(kTraceInfo, kTraceVoice,
+                         VoEId(_instanceId,_channelId),
+                         "SetSendDestination() extra local socket is created"
+                         " to facilitate unique source port");
+        }
+        else
+        {
+            WEBRTC_TRACE(kTraceInfo, kTraceVoice,
+                         VoEId(_instanceId,_channelId),
+                         "SetSendDestination() sourcePort equals the local"
+                         " receive port => no extra socket is created");
+        }
+    }
+
+    return 0;
+}
+#endif
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+WebRtc_Word32
+Channel::GetSendDestination(int& port,
+                            char ipAddr[64],
+                            int& sourcePort,
+                            int& RTCPport)
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::GetSendDestination()");
+
+    if (_externalTransport)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "GetSendDestination() conflict with external transport");
+        return -1;
+    }
+
+    char ipAddrTmp[UdpTransport::kIpAddressVersion6Length] = {0};
+    WebRtc_UWord16 rtpPort(0);
+    WebRtc_UWord16 rtcpPort(0);
+    WebRtc_UWord16 rtpSourcePort(0);
+    WebRtc_UWord16 rtcpSourcePort(0);
+
+    // Acquire sending socket information from the socket module
+    _socketTransportModule.SendSocketInformation(ipAddrTmp, rtpPort, rtcpPort);
+    _socketTransportModule.SourcePorts(rtpSourcePort, rtcpSourcePort);
+
+    // Deliver valid results to the user
+    port = static_cast<int> (rtpPort);
+    RTCPport = static_cast<int> (rtcpPort);
+    sourcePort = static_cast<int> (rtpSourcePort);
+    if (ipAddr != NULL)
+    {
+        strcpy(ipAddr, ipAddrTmp);
+    }
+
+    return 0;
+}
+#endif
+
+
 WebRtc_Word32
 Channel::SetNetEQPlayoutMode(NetEqModes mode)
 {
@@ -2088,6 +2628,24 @@
 
     CriticalSectionScoped cs(&_callbackCritSect);
 
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    // Sanity checks for default (non external transport) to avoid conflict with
+    // WebRtc sockets.
+    if (_socketTransportModule.SendSocketsInitialized())
+    {
+        _engineStatisticsPtr->SetLastError(VE_SEND_SOCKETS_CONFLICT,
+                                           kTraceError,
+                "RegisterExternalTransport() send sockets already initialized");
+        return -1;
+    }
+    if (_socketTransportModule.ReceiveSocketsInitialized())
+    {
+        _engineStatisticsPtr->SetLastError(VE_RECEIVE_SOCKETS_CONFLICT,
+                                           kTraceError,
+             "RegisterExternalTransport() receive sockets already initialized");
+        return -1;
+    }
+#endif
     if (_externalTransport)
     {
         _engineStatisticsPtr->SetLastError(VE_INVALID_OPERATION,
@@ -2117,81 +2675,396 @@
         return 0;
     }
     _externalTransport = false;
+#ifdef WEBRTC_EXTERNAL_TRANSPORT
     _transportPtr = NULL;
     WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
                  "DeRegisterExternalTransport() all transport is disabled");
+#else
+    _transportPtr = &_socketTransportModule;
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "DeRegisterExternalTransport() internal Transport is enabled");
+#endif
     return 0;
 }
 
 WebRtc_Word32
 Channel::ReceivedRTPPacket(const WebRtc_Word8* data, WebRtc_Word32 length)
 {
-  WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
-               "Channel::ReceivedRTPPacket()");
-
-  // Store playout timestamp for the received RTP packet
-  // to be used for upcoming delay estimations
-  WebRtc_UWord32 playoutTimestamp(0);
-  if (GetPlayoutTimeStamp(playoutTimestamp) == 0)
-  {
-    _playoutTimeStampRTP = playoutTimestamp;
-  }
-  // Dump the RTP packet to a file (if RTP dump is enabled).
-  if (_rtpDumpIn.DumpPacket((const WebRtc_UWord8*)data,
-                            (WebRtc_UWord16)length) == -1)
-  {
-    WEBRTC_TRACE(kTraceWarning, kTraceVoice,
-                 VoEId(_instanceId,_channelId),
-                 "Channel::SendPacket() RTP dump to input file failed");
-  }
-
-  // Deliver RTP packet to RTP/RTCP module for parsing
-  // The packet will be pushed back to the channel thru the
-  // OnReceivedPayloadData callback so we don't push it to the ACM here
-  if (_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)data,
-                                     (WebRtc_UWord16)length) == -1)
-  {
-    _engineStatisticsPtr->SetLastError(
-        VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
-        "Channel::IncomingRTPPacket() RTP packet is invalid");
-  }
-  return 0;
+    WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::ReceivedRTPPacket()");
+    const char dummyIP[] = "127.0.0.1";
+    IncomingRTPPacket(data, length, dummyIP, 0);
+    return 0;
 }
 
 WebRtc_Word32
 Channel::ReceivedRTCPPacket(const WebRtc_Word8* data, WebRtc_Word32 length)
 {
-  WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
-               "Channel::ReceivedRTCPPacket()");
-
-  // Store playout timestamp for the received RTCP packet
-  // which will be read by the GetRemoteRTCPData API
-  WebRtc_UWord32 playoutTimestamp(0);
-  if (GetPlayoutTimeStamp(playoutTimestamp) == 0)
-  {
-    _playoutTimeStampRTCP = playoutTimestamp;
-  }
-
-  // Dump the RTCP packet to a file (if RTP dump is enabled).
-  if (_rtpDumpIn.DumpPacket((const WebRtc_UWord8*)data,
-                            (WebRtc_UWord16)length) == -1)
-  {
-    WEBRTC_TRACE(kTraceWarning, kTraceVoice,
-                 VoEId(_instanceId,_channelId),
-                 "Channel::SendPacket() RTCP dump to input file failed");
-  }
-
-  // Deliver RTCP packet to RTP/RTCP module for parsing
-  if (_rtpRtcpModule->IncomingPacket((const WebRtc_UWord8*)data,
-                                     (WebRtc_UWord16)length) == -1)
-  {
-    _engineStatisticsPtr->SetLastError(
-        VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
-        "Channel::IncomingRTPPacket() RTCP packet is invalid");
-  }
-  return 0;
+    WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::ReceivedRTCPPacket()");
+    const char dummyIP[] = "127.0.0.1";
+    IncomingRTCPPacket(data, length, dummyIP, 0);
+    return 0;
 }
 
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+WebRtc_Word32
+Channel::GetSourceInfo(int& rtpPort, int& rtcpPort, char ipAddr[64])
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::GetSourceInfo()");
+
+    WebRtc_UWord16 rtpPortModule;
+    WebRtc_UWord16 rtcpPortModule;
+    char ipaddr[UdpTransport::kIpAddressVersion6Length] = {0};
+
+    if (_socketTransportModule.RemoteSocketInformation(ipaddr,
+                                                       rtpPortModule,
+                                                       rtcpPortModule) != 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError,
+            "GetSourceInfo() failed to retrieve remote socket information");
+        return -1;
+    }
+    strcpy(ipAddr, ipaddr);
+    rtpPort = rtpPortModule;
+    rtcpPort = rtcpPortModule;
+
+    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+        "GetSourceInfo() => rtpPort=%d, rtcpPort=%d, ipAddr=%s",
+        rtpPort, rtcpPort, ipAddr);
+    return 0;
+}
+
+WebRtc_Word32
+Channel::EnableIPv6()
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::EnableIPv6()");
+    if (_socketTransportModule.ReceiveSocketsInitialized() ||
+        _socketTransportModule.SendSocketsInitialized())
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_INVALID_OPERATION, kTraceError,
+            "EnableIPv6() socket layer is already initialized");
+        return -1;
+    }
+    if (_socketTransportModule.EnableIpV6() != 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKET_ERROR, kTraceError,
+            "EnableIPv6() failed to enable IPv6");
+        const UdpTransport::ErrorCode lastError =
+            _socketTransportModule.LastError();
+        WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                     "UdpTransport::LastError() => %d", lastError);
+        return -1;
+    }
+    return 0;
+}
+
+bool
+Channel::IPv6IsEnabled() const
+{
+    bool isEnabled = _socketTransportModule.IpV6Enabled();
+    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "IPv6IsEnabled() => %d", isEnabled);
+    return isEnabled;
+}
+
+WebRtc_Word32
+Channel::SetSourceFilter(int rtpPort, int rtcpPort, const char ipAddr[64])
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::SetSourceFilter()");
+    if (_socketTransportModule.SetFilterPorts(
+        static_cast<WebRtc_UWord16>(rtpPort),
+        static_cast<WebRtc_UWord16>(rtcpPort)) != 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError,
+            "SetSourceFilter() failed to set filter ports");
+        const UdpTransport::ErrorCode lastError =
+            _socketTransportModule.LastError();
+        WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                     "UdpTransport::LastError() => %d",
+                     lastError);
+        return -1;
+    }
+    const char* filterIpAddress = ipAddr;
+    if (_socketTransportModule.SetFilterIP(filterIpAddress) != 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_INVALID_IP_ADDRESS, kTraceError,
+            "SetSourceFilter() failed to set filter IP address");
+        const UdpTransport::ErrorCode lastError =
+           _socketTransportModule.LastError();
+        WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                     "UdpTransport::LastError() => %d", lastError);
+        return -1;
+    }
+    return 0;
+}
+
+WebRtc_Word32
+Channel::GetSourceFilter(int& rtpPort, int& rtcpPort, char ipAddr[64])
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::GetSourceFilter()");
+    WebRtc_UWord16 rtpFilterPort(0);
+    WebRtc_UWord16 rtcpFilterPort(0);
+    if (_socketTransportModule.FilterPorts(rtpFilterPort, rtcpFilterPort) != 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceWarning,
+            "GetSourceFilter() failed to retrieve filter ports");
+    }
+    char ipAddrTmp[UdpTransport::kIpAddressVersion6Length] = {0};
+    if (_socketTransportModule.FilterIP(ipAddrTmp) != 0)
+    {
+        // no filter has been configured (not seen as an error)
+        memset(ipAddrTmp,
+               0, UdpTransport::kIpAddressVersion6Length);
+    }
+    rtpPort = static_cast<int> (rtpFilterPort);
+    rtcpPort = static_cast<int> (rtcpFilterPort);
+    strcpy(ipAddr, ipAddrTmp);
+    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+        "GetSourceFilter() => rtpPort=%d, rtcpPort=%d, ipAddr=%s",
+        rtpPort, rtcpPort, ipAddr);
+    return 0;
+}
+
+WebRtc_Word32
+Channel::SetSendTOS(int DSCP, int priority, bool useSetSockopt)
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::SetSendTOS(DSCP=%d, useSetSockopt=%d)",
+                 DSCP, (int)useSetSockopt);
+
+    // Set TOS value and possibly try to force usage of setsockopt()
+    if (_socketTransportModule.SetToS(DSCP, useSetSockopt) != 0)
+    {
+        UdpTransport::ErrorCode lastSockError(
+            _socketTransportModule.LastError());
+        switch (lastSockError)
+        {
+        case UdpTransport::kTosError:
+            _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError,
+                                               "SetSendTOS() TOS error");
+            break;
+        case UdpTransport::kQosError:
+            _engineStatisticsPtr->SetLastError(
+                    VE_TOS_GQOS_CONFLICT, kTraceError,
+                    "SetSendTOS() GQOS error");
+            break;
+        case UdpTransport::kTosInvalid:
+            // can't switch SetSockOpt method without disabling TOS first, or
+            // SetSockopt() call failed
+            _engineStatisticsPtr->SetLastError(VE_TOS_INVALID, kTraceError,
+                                               "SetSendTOS() invalid TOS");
+            break;
+        case UdpTransport::kSocketInvalid:
+            _engineStatisticsPtr->SetLastError(VE_SOCKET_ERROR, kTraceError,
+                                               "SetSendTOS() invalid Socket");
+            break;
+        default:
+            _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError,
+                                               "SetSendTOS() TOS error");
+            break;
+        }
+        WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId),
+                     "UdpTransport =>  lastError = %d",
+                     lastSockError);
+        return -1;
+    }
+
+    // Set priority (PCP) value, -1 means don't change
+    if (-1 != priority)
+    {
+        if (_socketTransportModule.SetPCP(priority) != 0)
+        {
+            UdpTransport::ErrorCode lastSockError(
+                _socketTransportModule.LastError());
+            switch (lastSockError)
+            {
+            case UdpTransport::kPcpError:
+                _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError,
+                                                   "SetSendTOS() PCP error");
+                break;
+            case UdpTransport::kQosError:
+                _engineStatisticsPtr->SetLastError(
+                        VE_TOS_GQOS_CONFLICT, kTraceError,
+                        "SetSendTOS() GQOS conflict");
+                break;
+            case UdpTransport::kSocketInvalid:
+                _engineStatisticsPtr->SetLastError(
+                        VE_SOCKET_ERROR, kTraceError,
+                        "SetSendTOS() invalid Socket");
+                break;
+            default:
+                _engineStatisticsPtr->SetLastError(VE_TOS_ERROR, kTraceError,
+                                                   "SetSendTOS() PCP error");
+                break;
+            }
+            WEBRTC_TRACE(kTraceError, kTraceVoice,
+                         VoEId(_instanceId,_channelId),
+                         "UdpTransport =>  lastError = %d",
+                         lastSockError);
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+WebRtc_Word32
+Channel::GetSendTOS(int &DSCP, int& priority, bool &useSetSockopt)
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::GetSendTOS(DSCP=?, useSetSockopt=?)");
+    WebRtc_Word32 dscp(0), prio(0);
+    bool setSockopt(false);
+    if (_socketTransportModule.ToS(dscp, setSockopt) != 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError,
+            "GetSendTOS() failed to get TOS info");
+        return -1;
+    }
+    if (_socketTransportModule.PCP(prio) != 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError,
+            "GetSendTOS() failed to get PCP info");
+        return -1;
+    }
+    DSCP = static_cast<int> (dscp);
+    priority = static_cast<int> (prio);
+    useSetSockopt = setSockopt;
+    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,-1),
+                 "GetSendTOS() => DSCP=%d, priority=%d, useSetSockopt=%d",
+        DSCP, priority, (int)useSetSockopt);
+    return 0;
+}
+
+#if defined(_WIN32)
+WebRtc_Word32
+Channel::SetSendGQoS(bool enable, int serviceType, int overrideDSCP)
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::SetSendGQoS(enable=%d, serviceType=%d, "
+                 "overrideDSCP=%d)",
+                 (int)enable, serviceType, overrideDSCP);
+    if(!_socketTransportModule.ReceiveSocketsInitialized())
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKETS_NOT_INITED, kTraceError,
+            "SetSendGQoS() GQoS state must be set after sockets are created");
+        return -1;
+    }
+    if(!_socketTransportModule.SendSocketsInitialized())
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_DESTINATION_NOT_INITED, kTraceError,
+            "SetSendGQoS() GQoS state must be set after sending side is "
+            "initialized");
+        return -1;
+    }
+    if (enable &&
+       (serviceType != SERVICETYPE_BESTEFFORT) &&
+       (serviceType != SERVICETYPE_CONTROLLEDLOAD) &&
+       (serviceType != SERVICETYPE_GUARANTEED) &&
+       (serviceType != SERVICETYPE_QUALITATIVE))
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_INVALID_ARGUMENT, kTraceError,
+            "SetSendGQoS() Invalid service type");
+        return -1;
+    }
+    if (enable && ((overrideDSCP <  0) || (overrideDSCP > 63)))
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_INVALID_ARGUMENT, kTraceError,
+            "SetSendGQoS() Invalid overrideDSCP value");
+        return -1;
+    }
+
+    // Avoid GQoS/ToS conflict when user wants to override the default DSCP
+    // mapping
+    bool QoS(false);
+    WebRtc_Word32 sType(0);
+    WebRtc_Word32 ovrDSCP(0);
+    if (_socketTransportModule.QoS(QoS, sType, ovrDSCP))
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError,
+            "SetSendGQoS() failed to get QOS info");
+        return -1;
+    }
+    if (QoS && ovrDSCP == 0 && overrideDSCP != 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_TOS_GQOS_CONFLICT, kTraceError,
+            "SetSendGQoS() QOS is already enabled and overrideDSCP differs,"
+            " not allowed");
+        return -1;
+    }
+    const WebRtc_Word32 maxBitrate(0);
+    if (_socketTransportModule.SetQoS(enable,
+                                      static_cast<WebRtc_Word32>(serviceType),
+                                      maxBitrate,
+                                      static_cast<WebRtc_Word32>(overrideDSCP),
+                                      true))
+    {
+        UdpTransport::ErrorCode lastSockError(
+            _socketTransportModule.LastError());
+        switch (lastSockError)
+        {
+        case UdpTransport::kQosError:
+            _engineStatisticsPtr->SetLastError(VE_GQOS_ERROR, kTraceError,
+                                               "SetSendGQoS() QOS error");
+            break;
+        default:
+            _engineStatisticsPtr->SetLastError(VE_SOCKET_ERROR, kTraceError,
+                                               "SetSendGQoS() Socket error");
+            break;
+        }
+        WEBRTC_TRACE(kTraceError, kTraceVoice, VoEId(_instanceId,_channelId),
+                     "UdpTransport() => lastError = %d",
+                     lastSockError);
+        return -1;
+    }
+    return 0;
+}
+#endif
+
+#if defined(_WIN32)
+WebRtc_Word32
+Channel::GetSendGQoS(bool &enabled, int &serviceType, int &overrideDSCP)
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::GetSendGQoS(enable=?, serviceType=?, "
+                 "overrideDSCP=?)");
+
+    bool QoS(false);
+    WebRtc_Word32 serviceTypeModule(0);
+    WebRtc_Word32 overrideDSCPModule(0);
+    _socketTransportModule.QoS(QoS, serviceTypeModule, overrideDSCPModule);
+
+    enabled = QoS;
+    serviceType = static_cast<int> (serviceTypeModule);
+    overrideDSCP = static_cast<int> (overrideDSCPModule);
+
+    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "GetSendGQoS() => enabled=%d, serviceType=%d, overrideDSCP=%d",
+                 (int)enabled, serviceType, overrideDSCP);
+    return 0;
+}
+#endif
+#endif
+
 WebRtc_Word32
 Channel::SetPacketTimeoutNotification(bool enable, int timeoutSeconds)
 {
@@ -2327,6 +3200,65 @@
     return 0;
 }
 
+WebRtc_Word32
+Channel::SendUDPPacket(const void* data,
+                       unsigned int length,
+                       int& transmittedBytes,
+                       bool useRtcpSocket)
+{
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "Channel::SendUDPPacket()");
+    if (_externalTransport)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "SendUDPPacket() external transport is enabled");
+        return -1;
+    }
+    if (useRtcpSocket && !_rtpRtcpModule->RTCP())
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_RTCP_ERROR, kTraceError,
+            "SendUDPPacket() RTCP is disabled");
+        return -1;
+    }
+    if (!_sending)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_NOT_SENDING, kTraceError,
+            "SendUDPPacket() not sending");
+        return -1;
+    }
+
+    char* dataC = new char[length];
+    if (NULL == dataC)
+    {
+        _engineStatisticsPtr->SetLastError(
+            VE_NO_MEMORY, kTraceError,
+            "SendUDPPacket() memory allocation failed");
+        return -1;
+    }
+    memcpy(dataC, data, length);
+
+    transmittedBytes = SendPacketRaw(dataC, length, useRtcpSocket);
+
+    delete [] dataC;
+    dataC = NULL;
+
+    if (transmittedBytes <= 0)
+    {
+        _engineStatisticsPtr->SetLastError(
+                VE_SEND_ERROR, kTraceError,
+                "SendUDPPacket() transmission failed");
+        transmittedBytes = 0;
+        return -1;
+    }
+    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+                 "SendUDPPacket() => transmittedBytes=%d", transmittedBytes);
+    return 0;
+}
+
+
 int Channel::StartPlayingFileLocally(const char* fileName,
                                      const bool loop,
                                      const FileFormats format,
diff --git a/voice_engine/channel.h b/voice_engine/channel.h
index cdb0790..f1c5809 100644
--- a/voice_engine/channel.h
+++ b/voice_engine/channel.h
@@ -27,6 +27,9 @@
 #include "webrtc/voice_engine/shared_data.h"
 #include "webrtc/voice_engine/voice_engine_defines.h"
 
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+#include "webrtc/modules/udp_transport/interface/udp_transport.h"
+#endif
 #ifdef WEBRTC_SRTP
 #include "SrtpModule.h"
 #endif
@@ -62,6 +65,9 @@
     public RtpData,
     public RtpFeedback,
     public RtcpFeedback,
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    public UdpTransportData, // receiving packet from sockets
+#endif
     public FileCallback, // receiving notification from file player & recorder
     public Transport,
     public RtpAudioFeedback,
@@ -175,6 +181,9 @@
                                                int sampleTimeSeconds);
     WebRtc_Word32 GetPeriodicDeadOrAliveStatus(bool& enabled,
                                                int& sampleTimeSeconds);
+    WebRtc_Word32 SendUDPPacket(const void* data, unsigned int length,
+                                int& transmittedBytes, bool useRtcpSocket);
+
     // VoEFile
     int StartPlayingFileLocally(const char* fileName, const bool loop,
                                 const FileFormats format,
@@ -404,6 +413,18 @@
                               const WebRtc_UWord8 volume);
 
 public:
+    // From UdpTransportData in the Socket Transport module
+    void IncomingRTPPacket(const WebRtc_Word8* incomingRtpPacket,
+                           const WebRtc_Word32 rtpPacketLength,
+                           const char* fromIP,
+                           const WebRtc_UWord16 fromPort);
+
+    void IncomingRTCPPacket(const WebRtc_Word8* incomingRtcpPacket,
+                            const WebRtc_Word32 rtcpPacketLength,
+                            const char* fromIP,
+                            const WebRtc_UWord16 fromPort);
+
+public:
     // From Transport (called by the RTP/RTCP module)
     int SendPacket(int /*channel*/, const void *data, int len);
     int SendRTCPPacket(int /*channel*/, const void *data, int len);
@@ -476,6 +497,16 @@
     {
         return _outputAudioLevel.Level();
     }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    bool SendSocketsInitialized() const
+    {
+        return _socketTransportModule.SendSocketsInitialized();
+    }
+    bool ReceiveSocketsInitialized() const
+    {
+        return _socketTransportModule.ReceiveSocketsInitialized();
+    }
+#endif
     WebRtc_UWord32 Demultiplex(const AudioFrame& audioFrame);
     WebRtc_UWord32 PrepareEncodeAndSend(int mixingFrequency);
     WebRtc_UWord32 EncodeAndSend();
@@ -504,6 +535,10 @@
 private:
     scoped_ptr<RtpRtcp> _rtpRtcpModule;
     AudioCodingModule& _audioCodingModule;
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    WebRtc_UWord8 _numSocketThreads;
+    UdpTransport& _socketTransportModule;
+#endif
 #ifdef WEBRTC_SRTP
     SrtpModule& _srtpModule;
 #endif
diff --git a/voice_engine/include/voe_base.h b/voice_engine/include/voe_base.h
index 70cbab1..84cd4fc 100644
--- a/voice_engine/include/voe_base.h
+++ b/voice_engine/include/voe_base.h
@@ -14,6 +14,7 @@
 //  - Initialization and termination.
 //  - Trace information on text files or via callbacks.
 //  - Multi-channel support (mixing, sending to multiple destinations etc.).
+//  - Call setup (port and address) for receiving and sending sides.
 //
 // To support other codecs than G.711, the VoECodec sub-API must be utilized.
 //
@@ -139,6 +140,28 @@
     // Deletes an existing channel and releases the utilized resources.
     virtual int DeleteChannel(int channel) = 0;
 
+    // Sets the local receiver port and address for a specified
+    // |channel| number.
+    virtual int SetLocalReceiver(int channel, int port,
+                                 int RTCPport = kVoEDefault,
+                                 const char ipAddr[64] = NULL,
+                                 const char multiCastAddr[64] = NULL) = 0;
+
+    // Gets the local receiver port and address for a specified
+    // |channel| number.
+    virtual int GetLocalReceiver(int channel, int& port, int& RTCPport,
+                                 char ipAddr[64]) = 0;
+
+    // Sets the destination port and address for a specified |channel| number.
+    virtual int SetSendDestination(int channel, int port,
+                                   const char ipAddr[64],
+                                   int sourcePort = kVoEDefault,
+                                   int RTCPport = kVoEDefault) = 0;
+
+    // Gets the destination port and address for a specified |channel| number.
+    virtual int GetSendDestination(int channel, int& port, char ipAddr[64],
+                                   int& sourcePort, int& RTCPport) = 0;
+
     // Prepares and initiates the VoiceEngine for reception of
     // incoming RTP/RTCP packets on the specified |channel|.
     virtual int StartReceive(int channel) = 0;
diff --git a/voice_engine/include/voe_network.h b/voice_engine/include/voe_network.h
index 9a2ff73..10acf1c 100644
--- a/voice_engine/include/voe_network.h
+++ b/voice_engine/include/voe_network.h
@@ -11,6 +11,9 @@
 // This sub-API supports the following functionalities:
 //
 //  - External protocol support.
+//  - Extended port and address APIs.
+//  - Port and address filters.
+//  - Windows GQoS functions.
 //  - Packet timeout notification.
 //  - Dead-or-Alive connection observations.
 //  - Transmission of raw RTP/RTCP packets into existing channels.
@@ -90,6 +93,49 @@
     virtual int ReceivedRTCPPacket(
         int channel, const void* data, unsigned int length) = 0;
 
+    // Gets the source ports and IP address of incoming packets on a
+    // specific |channel|.
+    virtual int GetSourceInfo(
+        int channel, int& rtpPort, int& rtcpPort, char ipAddr[64]) = 0;
+
+    // Gets the local (host) IP address.
+    virtual int GetLocalIP(char ipAddr[64], bool ipv6 = false) = 0;
+
+    // Enables IPv6 for a specified |channel|.
+    virtual int EnableIPv6(int channel) = 0;
+
+    // Gets the current IPv6 staus for a specified |channel|.
+    virtual bool IPv6IsEnabled(int channel) = 0;
+
+    // Enables a port and IP address filter for incoming packets on a
+    // specific |channel|.
+    virtual int SetSourceFilter(int channel,
+        int rtpPort, int rtcpPort = 0, const char ipAddr[64] = 0) = 0;
+
+    // Gets the current port and IP-address filter for a specified |channel|.
+    virtual int GetSourceFilter(
+        int channel, int& rtpPort, int& rtcpPort, char ipAddr[64]) = 0;
+
+    // Sets the six-bit Differentiated Services Code Point (DSCP) in the
+    // IP header of the outgoing stream for a specific |channel|.
+    virtual int SetSendTOS(int channel,
+        int DSCP, int priority = -1, bool useSetSockopt = false) = 0;
+
+    // Gets the six-bit DSCP in the IP header of the outgoing stream for
+    // a specific channel.
+    virtual int GetSendTOS(
+        int channel, int& DSCP, int& priority, bool& useSetSockopt) = 0;
+
+    // Sets the Generic Quality of Service (GQoS) service level.
+    // The Windows operating system then maps to a Differentiated Services
+    // Code Point (DSCP) and to an 802.1p setting. [Windows only]
+    virtual int SetSendGQoS(
+        int channel, bool enable, int serviceType, int overrideDSCP = 0) = 0;
+
+    // Gets the Generic Quality of Service (GQoS) service level.
+    virtual int GetSendGQoS(
+        int channel, bool& enabled, int& serviceType, int& overrideDSCP) = 0;
+
     // Enables or disables warnings that report if packets have not been
     // received in |timeoutSeconds| seconds for a specific |channel|.
     virtual int SetPacketTimeoutNotification(
@@ -115,6 +161,12 @@
     virtual int GetPeriodicDeadOrAliveStatus(
         int channel, bool& enabled, int& sampleTimeSeconds) = 0;
 
+    // Handles sending a raw UDP data packet over an existing RTP or RTCP
+    // socket.
+    virtual int SendUDPPacket(
+        int channel, const void* data, unsigned int length,
+        int& transmittedBytes, bool useRtcpSocket = false) = 0;
+
 protected:
     VoENetwork() {}
     virtual ~VoENetwork() {}
diff --git a/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h b/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h
index c5f0500..bbdd64d 100644
--- a/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h
+++ b/voice_engine/test/auto_test/fixtures/after_initialization_fixture.h
@@ -13,30 +13,9 @@
 
 #include "before_initialization_fixture.h"
 #include "scoped_ptr.h"
-#include "webrtc/common_types.h"
 
 class TestErrorObserver;
 
-class LoopBackTransport : public webrtc::Transport {
- public:
-  LoopBackTransport(webrtc::VoENetwork* voe_network)
-      : voe_network_(voe_network) {
-  }
-
-  virtual int SendPacket(int channel, const void *data, int len) {
-    voe_network_->ReceivedRTPPacket(channel, data, len);
-    return len;
-  }
-
-  virtual int SendRTCPPacket(int channel, const void *data, int len) {
-    voe_network_->ReceivedRTCPPacket(channel, data, len);
-    return len;
-  }
-
- private:
-  webrtc::VoENetwork* voe_network_;
-};
-
 // This fixture initializes the voice engine in addition to the work
 // done by the before-initialization fixture. It also registers an error
 // observer which will fail tests on error callbacks. This fixture is
diff --git a/voice_engine/test/auto_test/fixtures/after_streaming_fixture.cc b/voice_engine/test/auto_test/fixtures/after_streaming_fixture.cc
index 353888a..d1e6039 100644
--- a/voice_engine/test/auto_test/fixtures/after_streaming_fixture.cc
+++ b/voice_engine/test/auto_test/fixtures/after_streaming_fixture.cc
@@ -12,6 +12,8 @@
 
 #include <cstring>
 
+static const char* kLoopbackIp = "127.0.0.1";
+
 AfterStreamingFixture::AfterStreamingFixture()
     : channel_(voe_base_->CreateChannel()) {
   EXPECT_GE(channel_, 0);
@@ -28,9 +30,7 @@
   voe_file_->StopPlayingFileAsMicrophone(channel_);
   PausePlaying();
 
-  EXPECT_EQ(0, voe_network_->DeRegisterExternalTransport(channel_));
   voe_base_->DeleteChannel(channel_);
-  delete transport_;
 }
 
 void AfterStreamingFixture::SwitchToManualMicrophone() {
@@ -59,8 +59,8 @@
 }
 
 void AfterStreamingFixture::SetUpLocalPlayback() {
-  transport_ = new LoopBackTransport(voe_network_);
-  EXPECT_EQ(0, voe_network_->RegisterExternalTransport(channel_, *transport_));
+  EXPECT_EQ(0, voe_base_->SetSendDestination(channel_, 8000, kLoopbackIp));
+  EXPECT_EQ(0, voe_base_->SetLocalReceiver(0, 8000));
 
   webrtc::CodecInst codec;
   codec.channels = 1;
diff --git a/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h b/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h
index 26e37a7..6b0a61f 100644
--- a/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h
+++ b/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h
@@ -42,8 +42,6 @@
 
  private:
   void SetUpLocalPlayback();
-
-  LoopBackTransport* transport_;
 };
 
 
diff --git a/voice_engine/test/auto_test/standard/mixing_test.cc b/voice_engine/test/auto_test/standard/mixing_test.cc
index 1d2aea3..6a90c07 100644
--- a/voice_engine/test/auto_test/standard/mixing_test.cc
+++ b/voice_engine/test/auto_test/standard/mixing_test.cc
@@ -32,13 +32,7 @@
     : input_filename_(test::OutputPath() + "mixing_test_input.pcm"),
       output_filename_(test::OutputPath() + "mixing_test_output.pcm") {
   }
-  void SetUp() {
-    transport_ = new LoopBackTransport(voe_network_);
-  }
-  void TearDown() {
-    delete transport_;
-  }
-  
+
   // Creates and mixes |num_remote_streams| which play a file "as microphone"
   // with |num_local_streams| which play a file "locally", using a constant
   // amplitude of |input_value|. The local streams manifest as "anonymous"
@@ -171,7 +165,8 @@
   // Start up a single remote stream.
   void StartRemoteStream(int stream, const CodecInst& codec_inst, int port) {
     EXPECT_EQ(0, voe_codec_->SetRecPayloadType(stream, codec_inst));
-    EXPECT_EQ(0, voe_network_->RegisterExternalTransport(stream, *transport_));
+    EXPECT_EQ(0, voe_base_->SetLocalReceiver(stream, port));
+    EXPECT_EQ(0, voe_base_->SetSendDestination(stream, port, "127.0.0.1"));
     EXPECT_EQ(0, voe_base_->StartReceive(stream));
     EXPECT_EQ(0, voe_base_->StartPlayout(stream));
     EXPECT_EQ(0, voe_codec_->SetSendCodec(stream, codec_inst));
@@ -185,14 +180,12 @@
       EXPECT_EQ(0, voe_base_->StopSend(streams[i]));
       EXPECT_EQ(0, voe_base_->StopPlayout(streams[i]));
       EXPECT_EQ(0, voe_base_->StopReceive(streams[i]));
-      EXPECT_EQ(0, voe_network_->DeRegisterExternalTransport(streams[i]));
       EXPECT_EQ(0, voe_base_->DeleteChannel(streams[i]));
     }
   }
 
   const std::string input_filename_;
   const std::string output_filename_;
-  LoopBackTransport* transport_;
 };
 
 // These tests assume a maximum of three mixed participants. We typically allow
diff --git a/voice_engine/test/auto_test/standard/network_before_streaming_test.cc b/voice_engine/test/auto_test/standard/network_before_streaming_test.cc
new file mode 100644
index 0000000..7a41e80
--- /dev/null
+++ b/voice_engine/test/auto_test/standard/network_before_streaming_test.cc
@@ -0,0 +1,55 @@
+/*
+ *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
+ *
+ *  Use of this source code is governed by a BSD-style license
+ *  that can be found in the LICENSE file in the root of the source
+ *  tree. An additional intellectual property rights grant can be found
+ *  in the file PATENTS.  All contributing project authors may
+ *  be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "after_initialization_fixture.h"
+
+class NetworkBeforeStreamingTest : public AfterInitializationFixture {
+ protected:
+  void SetUp() {
+    channel_ = voe_base_->CreateChannel();
+  }
+
+  void TearDown() {
+    voe_base_->DeleteChannel(channel_);
+  }
+
+  int channel_;
+};
+
+TEST_F(NetworkBeforeStreamingTest,
+    GetSourceInfoReturnsEmptyValuesForUnconfiguredChannel) {
+  char src_ip[32] = "0.0.0.0";
+  int src_rtp_port = 1234;
+  int src_rtcp_port = 1235;
+
+  EXPECT_EQ(0, voe_network_->GetSourceInfo(
+      channel_, src_rtp_port, src_rtcp_port, src_ip));
+  EXPECT_EQ(0, src_rtp_port);
+  EXPECT_EQ(0, src_rtcp_port);
+  EXPECT_STRCASEEQ("", src_ip);
+}
+
+TEST_F(NetworkBeforeStreamingTest,
+    GetSourceFilterReturnsEmptyValuesForUnconfiguredChannel) {
+  int filter_port = -1;
+  int filter_port_rtcp = -1;
+  char filter_ip[32] = "0.0.0.0";
+
+  EXPECT_EQ(0, voe_network_->GetSourceFilter(
+      channel_, filter_port, filter_port_rtcp, filter_ip));
+
+  EXPECT_EQ(0, filter_port);
+  EXPECT_EQ(0, filter_port_rtcp);
+  EXPECT_STRCASEEQ("", filter_ip);
+}
+
+TEST_F(NetworkBeforeStreamingTest, SetSourceFilterSucceeds) {
+  EXPECT_EQ(0, voe_network_->SetSourceFilter(channel_, 0));
+}
diff --git a/voice_engine/test/auto_test/standard/network_test.cc b/voice_engine/test/auto_test/standard/network_test.cc
index f4713dc..8bf2d11 100644
--- a/voice_engine/test/auto_test/standard/network_test.cc
+++ b/voice_engine/test/auto_test/standard/network_test.cc
@@ -23,6 +23,79 @@
 
 using ::testing::Between;
 
+TEST_F(NetworkTest, GetSourceInfoReturnsPortsAndIpAfterReceivingPackets) {
+  // Give some time to send speech packets.
+  Sleep(200);
+
+  int rtp_port = 0;
+  int rtcp_port = 0;
+  char source_ip[32] = "127.0.0.1";
+
+  EXPECT_EQ(0, voe_network_->GetSourceInfo(channel_, rtp_port, rtcp_port,
+      source_ip));
+
+  EXPECT_EQ(kDefaultRtpPort, rtp_port);
+  EXPECT_EQ(kDefaultRtcpPort, rtcp_port);
+}
+
+TEST_F(NetworkTest, NoFilterIsEnabledByDefault) {
+  int filter_rtp_port = -1;
+  int filter_rtcp_port = -1;
+  char filter_ip[64] = { 0 };
+
+  EXPECT_EQ(0, voe_network_->GetSourceFilter(
+      channel_, filter_rtp_port, filter_rtcp_port, filter_ip));
+
+  EXPECT_EQ(0, filter_rtp_port);
+  EXPECT_EQ(0, filter_rtcp_port);
+  EXPECT_STREQ("", filter_ip);
+}
+
+TEST_F(NetworkTest, ManualCanFilterRtpPort) {
+  TEST_LOG("No filter, should hear audio.\n");
+  Sleep(1000);
+
+  int port_to_block = kDefaultRtpPort + 10;
+  EXPECT_EQ(0, voe_network_->SetSourceFilter(channel_, port_to_block));
+
+  // Changes should take effect immediately.
+  int filter_rtp_port = -1;
+  int filter_rtcp_port = -1;
+  char filter_ip[64] = { 0 };
+
+  EXPECT_EQ(0, voe_network_->GetSourceFilter(
+      channel_, filter_rtp_port, filter_rtcp_port, filter_ip));
+
+  EXPECT_EQ(port_to_block, filter_rtp_port);
+
+  TEST_LOG("Now filtering port %d, should not hear audio.\n", port_to_block);
+  Sleep(1000);
+
+  TEST_LOG("Removing filter, should hear audio.\n");
+  EXPECT_EQ(0, voe_network_->SetSourceFilter(channel_, 0));
+  Sleep(1000);
+}
+
+TEST_F(NetworkTest, ManualCanFilterIp) {
+  TEST_LOG("You should hear audio.\n");
+  Sleep(1000);
+
+  int rtcp_port_to_block = kDefaultRtcpPort + 10;
+  TEST_LOG("Filtering IP 10.10.10.10, should not hear audio.\n");
+  EXPECT_EQ(0, voe_network_->SetSourceFilter(
+      channel_, 0, rtcp_port_to_block, "10.10.10.10"));
+
+  int filter_rtp_port = -1;
+  int filter_rtcp_port = -1;
+  char filter_ip[64] = { 0 };
+  EXPECT_EQ(0, voe_network_->GetSourceFilter(
+      channel_, filter_rtp_port, filter_rtcp_port, filter_ip));
+
+  EXPECT_EQ(0, filter_rtp_port);
+  EXPECT_EQ(rtcp_port_to_block, filter_rtcp_port);
+  EXPECT_STREQ("10.10.10.10", filter_ip);
+}
+
 TEST_F(NetworkTest,
     CallsObserverOnTimeoutAndRestartWhenPacketTimeoutNotificationIsEnabled) {
   // First, get rid of the default, asserting observer and install our observer.
diff --git a/voice_engine/test/auto_test/standard/rtp_rtcp_test.cc b/voice_engine/test/auto_test/standard/rtp_rtcp_test.cc
index 7815288..3549cb3 100644
--- a/voice_engine/test/auto_test/standard/rtp_rtcp_test.cc
+++ b/voice_engine/test/auto_test/standard/rtp_rtcp_test.cc
@@ -101,10 +101,10 @@
     second_channel_ = voe_base_->CreateChannel();
     EXPECT_GE(second_channel_, 0);
 
-    transport_ = new LoopBackTransport(voe_network_);
-    EXPECT_EQ(0, voe_network_->RegisterExternalTransport(second_channel_,
-                                                         *transport_));
-    
+    EXPECT_EQ(0, voe_base_->SetSendDestination(
+        second_channel_, 8002, "127.0.0.1"));
+    EXPECT_EQ(0, voe_base_->SetLocalReceiver(
+        second_channel_, 8002));
     EXPECT_EQ(0, voe_base_->StartReceive(second_channel_));
     EXPECT_EQ(0, voe_base_->StartPlayout(second_channel_));
     EXPECT_EQ(0, voe_rtp_rtcp_->SetLocalSSRC(second_channel_, 5678));
@@ -115,13 +115,10 @@
   }
 
   void TearDown() {
-    EXPECT_EQ(0, voe_network_->DeRegisterExternalTransport(second_channel_));
     voe_base_->DeleteChannel(second_channel_);
-    delete transport_;
   }
 
   int second_channel_;
-  LoopBackTransport* transport_;
 };
 
 void RtcpAppHandler::OnApplicationDataReceived(
diff --git a/voice_engine/test/auto_test/voe_cpu_test.cc b/voice_engine/test/auto_test/voe_cpu_test.cc
index 2737ee8..14e4a00 100644
--- a/voice_engine/test/auto_test/voe_cpu_test.cc
+++ b/voice_engine/test/auto_test/voe_cpu_test.cc
@@ -8,8 +8,6 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "voe_cpu_test.h"
-
 #include <stdio.h>
 #include <string.h>
 #include <time.h>
@@ -18,8 +16,7 @@
 #include <conio.h>
 #endif
 
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
+#include "voe_cpu_test.h"
 
 using namespace webrtc;
 
@@ -48,7 +45,6 @@
   VoEFile* file = _mgr.FilePtr();
   VoECodec* codec = _mgr.CodecPtr();
   VoEAudioProcessing* apm = _mgr.APMPtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
 
   int channel(-1);
   CodecInst isac;
@@ -63,12 +59,8 @@
   CHECK(base->Init());
   channel = base->CreateChannel();
 
-  scoped_ptr<VoiceChannelTransport> voice_socket_transport(
-      new VoiceChannelTransport(voe_network, channel));
-
-  CHECK(voice_socket_transport->SetSendDestination("127.0.0.1", 5566));
-  CHECK(voice_socket_transport->SetLocalReceiver(5566));
-  
+  CHECK(base->SetLocalReceiver(channel, 5566));
+  CHECK(base->SetSendDestination(channel, 5566, "127.0.0.1"));
   CHECK(codec->SetRecPayloadType(channel, isac));
   CHECK(codec->SetSendCodec(channel, isac));
 
@@ -94,6 +86,7 @@
 
   base->DeleteChannel(channel);
   CHECK(base->Terminate());
+
   return 0;
 }
 
diff --git a/voice_engine/test/auto_test/voe_extended_test.cc b/voice_engine/test/auto_test/voe_extended_test.cc
index ce26992..d4c49c4 100644
--- a/voice_engine/test/auto_test/voe_extended_test.cc
+++ b/voice_engine/test/auto_test/voe_extended_test.cc
@@ -8,17 +8,22 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-#include "webrtc/voice_engine/test/auto_test/voe_extended_test.h"
-
 #include <stdio.h>
 #include <string.h>
 #include <vector>
 
+#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
+#include "webrtc/system_wrappers/interface/event_wrapper.h"
+#include "webrtc/system_wrappers/interface/ref_count.h"
+#include "webrtc/system_wrappers/interface/sleep.h"
+#include "webrtc/system_wrappers/interface/thread_wrapper.h"
 #include "webrtc/test/testsupport/fileutils.h"
 #include "webrtc/voice_engine/voice_engine_defines.h"
+#include "webrtc/voice_engine/test/auto_test/voe_extended_test.h"
 
 #if defined(_WIN32)
 #include <conio.h>
+#include <winsock2.h>
 #elif defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
 #include <netdb.h>
 #endif
@@ -153,6 +158,21 @@
   return len;
 }
 
+XTransport::XTransport(VoENetwork* netw, VoEFile* file) :
+  _netw(netw), _file(file) {
+}
+
+int XTransport::SendPacket(int channel, const void *data, int len) {
+  // loopback
+  // _netw->ReceivedRTPPacket(channel, data, len);
+
+  return 0;
+}
+
+int XTransport::SendRTCPPacket(int, const void *, int) {
+  return 0;
+}
+
 // ----------------------------------------------------------------------------
 //  VoERTPObserver
 // ----------------------------------------------------------------------------
@@ -235,14 +255,8 @@
   _playing[channel] = false;
   _sending[channel] = false;
 
-  VoENetwork* voe_network = _mgr.NetworkPtr();
-
-  voice_channel_transports_[channel].reset(
-      new VoiceChannelTransport(voe_network, channel));
-
-  voice_channel_transports_[channel]->SetSendDestination("127.0.0.1", rtpPort);
-  voice_channel_transports_[channel]->SetLocalReceiver(rtpPort);
-
+  voe_base_->SetLocalReceiver(channel, rtpPort);
+  voe_base_->SetSendDestination(channel, rtpPort, "127.0.0.1");
   if (listen) {
     _listening[channel] = true;
     voe_base_->StartReceive(channel);
@@ -272,7 +286,6 @@
     _sending[channel] = false;
     voe_base_->StopSend(channel);
   }
-  voice_channel_transports_[channel].reset(NULL);
 }
 
 void VoEExtendedTest::Play(int channel, unsigned int timeMillisec, bool addFileAsMicrophone,
@@ -320,7 +333,7 @@
   // instance variable since it is required in order to appease the
   // gods of darkness.
   VoEBase* voe_base_ = _mgr.BasePtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
+  VoENetwork* netw = _mgr.NetworkPtr();
 #ifdef _TEST_RTP_RTCP_
   VoERTP_RTCP* rtp = _mgr.RTP_RTCPPtr();
 #endif
@@ -542,6 +555,305 @@
   ANL();
 
   // ------------------------------------------------------------------------
+  // >> SetLocalReceiver
+  //
+  // State: VE not initialized, no existing channels
+  TEST_MUSTPASS(voe_base_->Init());
+
+  int ch;
+
+  TEST(SetLocalReceiver);
+  ANL();
+
+  // no channel created yet => should fail
+  TEST_MUSTPASS(!voe_base_->SetLocalReceiver(0, 100));
+  MARK();
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+
+  ch = voe_base_->CreateChannel();
+
+#ifdef WEBRTC_IOS
+  printf("\nNOTE: Local IP must be set in source code (line %d) \n",
+      __LINE__ + 1);
+  char* localIp = "127.0.0.1";
+#else
+  char localIp[64] = { 0 };
+  TEST_MUSTPASS(netw->GetLocalIP(localIp));
+  MARK();
+  // NOTE: This API is supported on Win, Mac and Linux and may fail or not
+  // return local IP for other platforms.
+#endif
+
+  // trivial invalid function calls
+  TEST_MUSTPASS(!voe_base_->SetLocalReceiver(ch+1, 12345));
+  MARK();
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+  TEST_MUSTPASS(!voe_base_->SetLocalReceiver(ch, -1));
+  MARK();
+  TEST_ERROR(VE_INVALID_PORT_NMBR);
+
+  // check conflict with ongoing receiving
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
+  MARK();
+  TEST_MUSTPASS(voe_base_->StartReceive(ch));
+  TEST_MUSTPASS(!voe_base_->SetLocalReceiver(ch, 12345));
+  MARK();
+  TEST_ERROR(VE_ALREADY_LISTENING);
+  TEST_MUSTPASS(voe_base_->StopReceive(ch));
+
+  // check conflict with ongoing transmission
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->StartSend(ch));
+  TEST_MUSTPASS(!voe_base_->SetLocalReceiver(ch, 12345));
+  MARK();
+  TEST_ERROR(VE_ALREADY_SENDING);
+  TEST_MUSTPASS(voe_base_->StopSend(ch));
+
+  // valid function calls
+  // Need to sleep between, otherwise it may fail for unknown reason
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
+  MARK();
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
+  MARK();
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, kVoEDefault, localIp));
+  MARK();
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, kVoEDefault, NULL,
+          "230.1.2.3"));
+  MARK();
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, kVoEDefault, localIp,
+          "230.1.2.3"));
+  MARK();
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, 5555, NULL));
+  MARK();
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
+  MARK();
+  SleepMs(100);
+
+  // STATE: no media but sockets exists and are binded to 12345 and 12346
+  // respectively
+
+  // Add some dynamic tests as well:
+
+  // ensure that last setting is used (cancels old settings)
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
+  MARK();
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 44444));
+  MARK();
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 54321));
+  MARK();
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 54321, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->StartReceive(ch));
+  TEST_MUSTPASS(voe_base_->StartSend(ch));
+  Play(ch, 1000, true, true);
+  TEST_MUSTPASS(voe_base_->StopSend(ch));
+  TEST_MUSTPASS(voe_base_->StopReceive(ch));
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
+
+  ANL();
+  AOK();
+  ANL();
+  ANL();
+
+  // >> end of SetLocalReceiver
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
+  // >> GetLocalReceiver
+  //
+  // State: VE initialized, no existing channels
+  TEST(GetLocalReceiver);
+  ANL();
+
+  int port;
+  char ipaddr[64];
+  int RTCPport;
+
+  ch = voe_base_->CreateChannel();
+
+  // verify non-configured (blank) local receiver
+  TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, port, RTCPport, ipaddr));
+  MARK();
+  TEST_MUSTPASS(port != 0);
+  TEST_MUSTPASS(RTCPport != 0);
+  TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
+
+  // check some trivial set/get combinations
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345))
+  TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, port, RTCPport, ipaddr));
+  MARK();
+  TEST_MUSTPASS(port != 12345);
+  TEST_MUSTPASS(RTCPport != 12346);
+  TEST_MUSTPASS(strcmp(ipaddr, "0.0.0.0") != 0); // now binded to "any" IP
+
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, 55555))
+  TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, port, RTCPport, ipaddr));
+  MARK();
+  TEST_MUSTPASS(port != 12345);
+  TEST_MUSTPASS(RTCPport != 55555);
+  TEST_MUSTPASS(strcmp(ipaddr, "0.0.0.0") != 0);
+
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, kVoEDefault, localIp))
+  TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, port, RTCPport, ipaddr));
+  MARK();
+  TEST_MUSTPASS(port != 12345);
+  TEST_MUSTPASS(RTCPport != 12346);
+  TEST_MUSTPASS(strcmp(ipaddr, localIp) != 0);
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
+
+  ANL();
+  AOK();
+  ANL();
+  ANL();
+
+  // >> end of GetLocalReceiver
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
+  // >> SetSendDestination
+  //
+  // State: VE initialized, no existing channels
+  TEST(SetSendDestination);
+  ANL();
+
+  // call without existing channel
+  TEST_MUSTPASS(!voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
+  MARK();
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+
+  ch = voe_base_->CreateChannel();
+
+  // trivial fail tests
+  TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 65536, "127.0.0.1"));
+  MARK();
+  TEST_ERROR(VE_INVALID_PORT_NMBR); // invalid RTP port
+  TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 12345, "127.0.0.1", 65536));
+  MARK();
+  TEST_ERROR(VE_INVALID_PORT_NMBR); // invalid source port
+  TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 12345, "127.0.0.1", kVoEDefault,
+          65536));
+  MARK();
+  TEST_ERROR(VE_INVALID_PORT_NMBR); // invalid RTCP port
+  TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 12345, "127.0.0.300"));
+  MARK();
+  TEST_ERROR(VE_INVALID_IP_ADDRESS); // invalid IP address
+
+  // sockets must be created first to support multi-cast (not required
+  // otherwise)
+  TEST_MUSTPASS(!voe_base_->SetSendDestination(ch, 55555, "230.0.0.1"));
+  MARK();
+  TEST_ERROR(VE_SOCKET_ERROR);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 55555)); // create sockets
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 55555, "230.0.0.1"));
+  MARK(); // should work now
+
+  voe_base_->DeleteChannel(0);
+  ch = voe_base_->CreateChannel();
+
+  // STATE: one channel created, no sockets exist
+
+  // valid function calls
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1"));
+  MARK();
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1", 44444));
+  MARK();
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1", kVoEDefault,
+          55555));
+  MARK();
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1", 44444,
+          55555));
+  MARK();
+
+  voe_base_->DeleteChannel(0);
+  ch = voe_base_->CreateChannel();
+
+  // create receive sockets first and then an extra pair of send sockets
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 44444));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 44444, "127.0.0.1", 11111));
+  MARK(); // binds to 11111
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
+
+  ANL();
+  AOK();
+  ANL();
+  ANL();
+
+  // >> end of SetSendDestination
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
+  // >> GetSendDestination
+  //
+  // State: VE initialized, no existing channels
+  TEST(GetSendDestination);
+  ANL();
+
+  int sourcePort;
+
+  ch = voe_base_->CreateChannel();
+
+  // verify non-configured (blank) local receiver
+  TEST_MUSTPASS(voe_base_->GetSendDestination(ch, port, ipaddr, sourcePort,
+          RTCPport));
+  MARK();
+  TEST_MUSTPASS(port != 0);
+  TEST_MUSTPASS(sourcePort != 0);
+  TEST_MUSTPASS(RTCPport != 0);
+  TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
+
+  // check some trivial set/get combinations
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 44444, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->GetSendDestination(ch, port, ipaddr, sourcePort,
+          RTCPport));
+  MARK();
+  TEST_MUSTPASS(port != 44444);
+  TEST_MUSTPASS(sourcePort != 0); // should be 0 since no local receiver has
+  // NOT been defined yet
+  TEST_MUSTPASS(RTCPport != 44445);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 55555));
+  TEST_MUSTPASS(voe_base_->GetSendDestination(ch, port, ipaddr, sourcePort,
+          RTCPport));
+  MARK();
+  TEST_MUSTPASS(port != 44444);
+  TEST_MUSTPASS(sourcePort != 55555); // should be equal to local port
+  TEST_MUSTPASS(RTCPport != 44445);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  voe_base_->DeleteChannel(0);
+  ch = voe_base_->CreateChannel();
+
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 44444, "127.0.0.1"));
+  // NULL as IP-address input should work as well
+  TEST_MUSTPASS(voe_base_->GetSendDestination(ch, port, NULL, sourcePort,
+          RTCPport));
+  MARK();
+  TEST_MUSTPASS(port != 44444);
+  TEST_MUSTPASS(sourcePort != 0);
+  TEST_MUSTPASS(RTCPport != 44445);
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(ch));
+
+  ANL();
+  AOK();
+  ANL();
+  ANL();
+
+  // >> end of GetLocalReceiver
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
   // >> StartReceive
   // >> StopReceive
   //
@@ -559,14 +871,14 @@
   MARK();
   TEST_ERROR(VE_CHANNEL_NOT_VALID);
 
-  int ch = voe_base_->CreateChannel();
+  ch = voe_base_->CreateChannel();
 
-  // must register external transport first.
+  // sockets must be created first
   TEST_MUSTPASS(!voe_base_->StartReceive(0));
   MARK();
-
-  ExtendedTestTransport* ptrTransport = new ExtendedTestTransport(voe_network);
-  TEST_MUSTPASS(voe_network ->RegisterExternalTransport(ch, *ptrTransport));
+  TEST_ERROR(VE_SOCKETS_NOT_INITED);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 55555));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
   MARK(); // should work this time
 
   // enable again (should work)
@@ -580,6 +892,7 @@
   MARK();
 
   // Verify in loopback
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 55555, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartSend(ch));
   Play(ch, 1000, true, true);
   TEST_MUSTPASS(voe_base_->StopSend(ch));
@@ -587,15 +900,16 @@
   MARK();
 
   voe_base_->DeleteChannel(0);
-  delete ptrTransport;
   ch = voe_base_->CreateChannel();
 
   // Ensure that it is OK to add delay between SetLocalReceiver and StarListen
   TEST_LOG("\nspeak after 2 seconds and ensure that no delay is added:\n");
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 55555));
 
   Sleep(2000, true); // adding emulated delay here
 
   TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 55555, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartSend(ch));
   Play(ch, 2000, true, true);
   TEST_MUSTPASS(voe_base_->StopSend(ch));
@@ -608,23 +922,23 @@
 
   for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
     ch = voe_base_->CreateChannel();
+    TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 11111+2*i));
+    TEST_MUSTPASS(voe_base_->StartReceive(ch));
     MARK();
   }
   for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
-    voe_base_->DeleteChannel(i);
+    TEST_MUSTPASS(voe_base_->StopReceive(i));
     MARK();
+    voe_base_->DeleteChannel(i);
   }
   for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
     ch = voe_base_->CreateChannel();
-    ExtendedTestTransport* ptrTransport =
-        new ExtendedTestTransport(voe_network);
-    TEST_MUSTPASS(voe_network ->RegisterExternalTransport(ch, *ptrTransport));
+    TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 11111+2*i));
     TEST_MUSTPASS(voe_base_->StartReceive(ch));
     MARK();
     TEST_MUSTPASS(voe_base_->StopReceive(ch));
     MARK();
     voe_base_->DeleteChannel(ch);
-    delete ptrTransport;
   }
 
   ANL();
@@ -719,24 +1033,25 @@
   MARK();
   TEST_ERROR(VE_DESTINATION_NOT_INITED);
 
-  
   // initialize destination and try again (should work even without existing
   // sockets)
-  ptrTransport = new ExtendedTestTransport(voe_network);
-  TEST_MUSTPASS(voe_network ->RegisterExternalTransport(ch, *ptrTransport));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartSend(ch));
   MARK();
   SleepMs(100);
 
+  // STATE: sockets should now have been created automatically at the first
+  // transmitted packet should be binded to 33333 and "0.0.0.0"
   TEST_MUSTPASS(voe_base_->StopSend(ch));
   MARK();
 
   voe_base_->DeleteChannel(ch);
-  delete ptrTransport;
   ch = voe_base_->CreateChannel();
 
-  ptrTransport = new ExtendedTestTransport(voe_network);
-  TEST_MUSTPASS(voe_network ->RegisterExternalTransport(ch, *ptrTransport));
+  // try loopback with unique send sockets (closed when channel is deleted or
+  // new source is set)
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 33333));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333, "127.0.0.1", 44444));
   TEST_MUSTPASS(voe_base_->StartSend(ch));
   MARK();
   TEST_MUSTPASS(voe_base_->StartReceive(ch));
@@ -746,7 +1061,31 @@
   TEST_MUSTPASS(voe_base_->StopReceive(ch));
 
   voe_base_->DeleteChannel(ch);
+  ANL();
 
+  // Multi-channel tests
+  for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
+    ch = voe_base_->CreateChannel();
+    TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 33333 + 2*i));
+    TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33333 + 2*i, "127.0.0.1"));
+    TEST_MUSTPASS(voe_base_->StartSend(ch));
+    MARK();
+  }
+  for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
+    TEST_MUSTPASS(voe_base_->StopSend(i));
+    MARK();
+    voe_base_->DeleteChannel(i);
+  }
+  for (i = 0; i < voe_base_->MaxNumOfChannels(); i++) {
+    ch = voe_base_->CreateChannel();
+    TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 45633 + 2*i));
+    TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 45633 + 2*i, "127.0.0.1"));
+    TEST_MUSTPASS(voe_base_->StartSend(ch));
+    MARK();
+    TEST_MUSTPASS(voe_base_->StopSend(ch));
+    MARK();
+    voe_base_->DeleteChannel(ch);
+  }
   ANL();
   AOK();
   ANL();
@@ -824,11 +1163,9 @@
 
   ch = voe_base_->CreateChannel();
 
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(voe_network, ch));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
 
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
   TEST_MUSTPASS(voe_base_->StartReceive(ch));
   TEST_MUSTPASS(voe_base_->StartSend(ch));
   TEST_MUSTPASS(voe_base_->StartPlayout(ch));
@@ -869,9 +1206,9 @@
 #ifdef _TEST_RTP_RTCP_
   TEST_MUSTPASS(rtp->SetRTCP_CNAME(ch, "Johnny"));
 #endif
-  voice_channel_transport.reset(new VoiceChannelTransport(voe_network, ch));
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345, 12349));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1", kVoEDefault,
+          12349));
 
   TEST_MUSTPASS(voe_base_->StartReceive(ch));
   TEST_MUSTPASS(voe_base_->StartSend(ch));
@@ -889,11 +1226,18 @@
   TEST_MUSTPASS(rtp->GetRemoteRTCP_CNAME(ch, tmpStr));
   TEST_MUSTPASS(_stricmp("Johnny", tmpStr));
 #endif
+  int rtpPort(0), rtcpPort(0);
+  char ipAddr[64] = { 0 };
+  TEST_MUSTPASS(netw->GetSourceInfo(ch, rtpPort, rtcpPort, ipAddr));
+  TEST_MUSTPASS(12349 != rtcpPort);
   TEST_MUSTPASS(voe_base_->StopSend(ch));
   TEST_MUSTPASS(voe_base_->StopPlayout(ch));
   TEST_MUSTPASS(voe_base_->StopReceive(ch));
 
   // Call StartSend before StartReceive
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
+
   TEST_MUSTPASS(voe_base_->StartSend(ch));
   TEST_MUSTPASS(voe_base_->StartReceive(ch));
   TEST_MUSTPASS(voe_base_->StartPlayout(ch));
@@ -907,6 +1251,9 @@
   TEST_MUSTPASS(voe_base_->StopReceive(ch));
 
   // Try again using same ports
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
+
   TEST_MUSTPASS(voe_base_->StartSend(ch));
   TEST_MUSTPASS(voe_base_->StartReceive(ch));
   TEST_MUSTPASS(voe_base_->StartPlayout(ch));
@@ -917,17 +1264,38 @@
   SleepMs(7000); // Make sure we get RTCP packet
   PAUSE
 
+  // Verify correct RTCP source port
+  TEST_MUSTPASS(netw->GetSourceInfo(ch, rtpPort, rtcpPort, ipAddr));
+  TEST_MUSTPASS(12345+1 != rtcpPort);
   TEST_MUSTPASS(voe_base_->StopSend(ch));
   TEST_MUSTPASS(voe_base_->StopPlayout(ch));
   TEST_MUSTPASS(voe_base_->StopReceive(ch));
 
   voe_base_->DeleteChannel(ch);
-
   ch = voe_base_->CreateChannel();
-  voice_channel_transport.reset(new VoiceChannelTransport(voe_network, ch));
 
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
+  // Try with extra send socket
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 22222));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 22222, "127.0.0.1", 11111));
+
+  TEST_MUSTPASS(voe_base_->StartReceive(ch));
+  TEST_MUSTPASS(voe_base_->StartSend(ch));
+  TEST_MUSTPASS(voe_base_->StartPlayout(ch));
+
+  TEST_LOG("\nfull duplex is now activated (4)\n");
+
+  PAUSE
+
+  TEST_MUSTPASS(voe_base_->StopSend(ch));
+  TEST_MUSTPASS(voe_base_->StopPlayout(ch));
+  TEST_MUSTPASS(voe_base_->StopReceive(ch));
+
+  // repeat default case starting with a fresh channel
+
+  voe_base_->DeleteChannel(ch);
+  ch = voe_base_->CreateChannel();
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1"));
 
   TEST_MUSTPASS(voe_base_->StartReceive(ch));
   TEST_MUSTPASS(voe_base_->StartSend(ch));
@@ -942,6 +1310,7 @@
   TEST_MUSTPASS(voe_base_->StopReceive(ch));
 
   // restart call again
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 12345));
   TEST_MUSTPASS(voe_base_->StartReceive(ch));
   TEST_MUSTPASS(voe_base_->StartPlayout(ch));
   TEST_MUSTPASS(voe_base_->StartSend(ch));
@@ -954,15 +1323,35 @@
   TEST_MUSTPASS(voe_base_->StopPlayout(ch));
   TEST_MUSTPASS(voe_base_->StopReceive(ch));
 
+  // force sending from new socket
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 12345, "127.0.0.1", 12350,
+          12359));
+  TEST_MUSTPASS(voe_base_->StartReceive(ch));
+  TEST_MUSTPASS(voe_base_->StartPlayout(ch));
+  TEST_MUSTPASS(voe_base_->StartSend(ch));
+  TEST_LOG("\nfull duplex is now activated (7)\n");
+
+  PAUSE
+
+  // Test getting send settings
+  TEST_MUSTPASS(voe_base_->GetSendDestination(ch, rtpPort, ipAddr, sourcePort,
+          rtcpPort));
+  TEST_MUSTPASS(12345 != rtpPort);
+  TEST_MUSTPASS(_stricmp("127.0.0.1", ipAddr));
+  TEST_MUSTPASS(12350 != sourcePort);
+  TEST_MUSTPASS(12359 != rtcpPort);
+
+  TEST_MUSTPASS(voe_base_->StopSend(ch));
+  TEST_MUSTPASS(voe_base_->StopPlayout(ch));
+  TEST_MUSTPASS(voe_base_->StopReceive(ch));
+
   // new channel and new port
   ch = voe_base_->CreateChannel();
 
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport_2(
-      new VoiceChannelTransport(voe_network, ch));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch , 33221));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33221, "127.0.0.1"));
 
-  voice_channel_transport_2->SetSendDestination("127.0.0.1", 33221);
-  voice_channel_transport_2->SetLocalReceiver(33221);
-  
   TEST_MUSTPASS(voe_base_->StartReceive(ch));
   TEST_MUSTPASS(voe_base_->StartPlayout(ch));
   TEST_MUSTPASS(voe_base_->StartSend(ch));
@@ -971,6 +1360,36 @@
 
   PAUSE
 
+  TEST_MUSTPASS(voe_base_->StopSend(ch));
+  TEST_MUSTPASS(voe_base_->StopPlayout(ch));
+  TEST_MUSTPASS(voe_base_->StopReceive(ch));
+
+  voe_base_->DeleteChannel(ch);
+  ch = voe_base_->CreateChannel();
+
+#ifndef WEBRTC_IOS
+  // bind to local IP and try again
+  strcpy(localIp, "127.0.0.1");
+#else
+  localIp = "127.0.0.1";
+#endif
+
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(ch, 33221, 12349, localIp));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(ch, 33221, localIp));
+
+  TEST_MUSTPASS(voe_base_->StartReceive(ch));
+  TEST_MUSTPASS(voe_base_->StartPlayout(ch));
+  TEST_MUSTPASS(voe_base_->StartSend(ch));
+
+  TEST_LOG("\nfull duplex is now activated (9)\n");
+
+  PAUSE
+
+  TEST_MUSTPASS(voe_base_->GetLocalReceiver(ch, rtpPort, rtcpPort, ipAddr));
+  TEST_MUSTPASS(33221 != rtpPort);
+  TEST_MUSTPASS(_stricmp(localIp, ipAddr));
+  TEST_MUSTPASS(12349 != rtcpPort);
+
   ANL();
   AOK();
   ANL();
@@ -1058,6 +1477,7 @@
 
   voe_base_->DeleteChannel(0);
   TEST_MUSTPASS(voe_base_->Terminate());
+
   return 0;
 }
 
@@ -1071,7 +1491,7 @@
   VoECallReport* report = _mgr.CallReportPtr();
   VoEFile* file = _mgr.FilePtr();
   VoEAudioProcessing* apm = _mgr.APMPtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
+  VoENetwork* netw = _mgr.NetworkPtr();
 
   PrepareTest("CallReport");
 
@@ -1096,10 +1516,8 @@
 
   TEST_MUSTPASS(voe_base_->Init());
   TEST_MUSTPASS(voe_base_->CreateChannel());
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(voe_network, 0));
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
@@ -1163,14 +1581,14 @@
   // All results should be -1 since dead-or-alive is not active
   TEST_MUSTPASS(report->GetDeadOrAliveSummary(0, nDead, nAlive) != -1);
   MARK();
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 1));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 1));
   SleepMs(2000);
   // All results should be >= 0 since dead-or-alive is active
   TEST_MUSTPASS(report->GetDeadOrAliveSummary(0, nDead, nAlive));
   MARK();
   TEST_MUSTPASS(nDead == -1);
   TEST_MUSTPASS(nAlive == -1)
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, false));
   AOK();
   ANL();
 
@@ -1223,7 +1641,6 @@
   VoEBase* voe_base_ = _mgr.BasePtr();
   VoECodec* codec = _mgr.CodecPtr();
   VoEFile* file = _mgr.FilePtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
 
 #ifdef _USE_EXTENDED_TRACE_
   TEST_MUSTPASS(VoiceEngine::SetTraceFile(
@@ -1240,8 +1657,14 @@
 
   TEST_MUSTPASS(voe_base_->Init());
   TEST_MUSTPASS(voe_base_->CreateChannel());
-  ExtendedTestTransport* ptrTransport = new ExtendedTestTransport(voe_network);
-  TEST_MUSTPASS(voe_network ->RegisterExternalTransport(0, *ptrTransport));
+#ifdef WEBRTC_EXTERNAL_TRANSPORT
+  ExtendedTestTransport* ptrTransport(NULL);
+  ptrTransport = new ExtendedTestTransport(netw);
+  TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
+#else
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
+#endif
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
@@ -1717,6 +2140,10 @@
   TEST_MUSTPASS(voe_base_->StopReceive(0));
 
   // start loopback streaming (PCMU is default)
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0,8000,"127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0,8000));
+#endif
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
@@ -1989,12 +2416,16 @@
   TEST(SetRecPayloadType - removing receive codecs);
   ANL();
 
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
+#endif
   TEST_MUSTPASS(voe_base_->StartSend(0));
   if (file) {
     TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0,
-                                                     _mgr.AudioFilename(),
-                                                     true,
-                                                     true));
+            _mgr.AudioFilename(),
+            true,
+            true));
   }
 
   // Scan all supported and valid codecs and remove from receiving db, then
@@ -2509,7 +2940,12 @@
 
   // set iSAC as sending codec
   // set iSAC-wb as sending codec
-  TEST_MUSTPASS(voe_network ->RegisterExternalTransport(0, *ptrTransport));
+#ifdef WEBRTC_EXTERNAL_TRANSPORT
+  TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
+#else
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8001, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8001));
+#endif
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
@@ -2555,8 +2991,10 @@
   TEST_LOG("Skipping extended iSAC API tests - "
       "WEBRTC_CODEC_ISAC not defined\n");
 #endif // #if defined(WEBRTC_CODEC_ISAC)
-  TEST_MUSTPASS(voe_network ->DeRegisterExternalTransport(0));
+#ifdef WEBRTC_EXTERNAL_TRANSPORT
+  TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
   delete ptrTransport;
+#endif
 
   TEST_MUSTPASS(voe_base_->DeleteChannel(0));
   TEST_MUSTPASS(voe_base_->Terminate());
@@ -2575,7 +3013,6 @@
   VoEDtmf* dtmf = _mgr.DtmfPtr();
   VoECodec* codec = _mgr.CodecPtr();
   VoEVolumeControl* volume = _mgr.VolumeControlPtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
 
   std::string output_path = webrtc::test::OutputPath();
   TEST_MUSTPASS(VoiceEngine::SetTraceFile(
@@ -2591,10 +3028,8 @@
   //#endif
   TEST_MUSTPASS(voe_base_->Init());
   TEST_MUSTPASS(voe_base_->CreateChannel());
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(voe_network, 0));
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
@@ -2904,7 +3339,6 @@
   VoEBase* voe_base_ = _mgr.BasePtr();
   VoEFile* file = _mgr.FilePtr();
   VoEEncryption* encrypt = _mgr.EncryptionPtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
 
 #ifdef _USE_EXTENDED_TRACE_
   TEST_MUSTPASS(VoiceEngine::SetTraceFile(
@@ -2920,10 +3354,8 @@
 #endif
   TEST_MUSTPASS(voe_base_->Init());
   TEST_MUSTPASS(voe_base_->CreateChannel());
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(voe_network, 0));
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
@@ -3418,7 +3850,6 @@
 
   VoEBase* voe_base_ = _mgr.BasePtr();
   VoEExternalMedia* xmedia = _mgr.ExternalMediaPtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
 
   // check if this interface is supported
   if (!xmedia) {
@@ -3436,10 +3867,8 @@
 #endif
   TEST_MUSTPASS(voe_base_->Init());
   TEST_MUSTPASS(voe_base_->CreateChannel());
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(voe_network, 0));
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
@@ -3544,7 +3973,6 @@
   VoEBase* voe_base_ = _mgr.BasePtr();
   VoEFile* file = _mgr.FilePtr();
   VoECodec* codec = _mgr.CodecPtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
 
 #ifdef _USE_EXTENDED_TRACE_
   TEST_MUSTPASS(VoiceEngine::SetTraceFile(
@@ -3561,10 +3989,8 @@
 
   TEST_MUSTPASS(voe_base_->Init());
   TEST_MUSTPASS(voe_base_->CreateChannel());
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(voe_network, 0));
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
@@ -3963,10 +4389,9 @@
     TEST_MUSTPASS(ch == -1);
     TEST_MUSTPASS(voe_base_->StopPlayout(ch));
   }
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport_1(
-      new VoiceChannelTransport(voe_network, 1));
-  voice_channel_transport_1->SetSendDestination("127.0.0.1", 12356);
-  voice_channel_transport_1->SetLocalReceiver(12356);
+
+  TEST_MUSTPASS(voe_base_->SetSendDestination(1, 12356, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(1, 12356));
   TEST_MUSTPASS(voe_base_->StartReceive(1));
   TEST_MUSTPASS(voe_base_->StopPlayout(1));
   TEST_MUSTPASS(voe_base_->StartSend(1));
@@ -4553,8 +4978,20 @@
 int VoEExtendedTest::TestNetwork() {
   PrepareTest("Network");
 
+#ifdef WEBRTC_ANDROID
+  int sleepTime = 200;
+  int sleepTime2 = 250;
+#elif defined(WEBRTC_IOS) // WEBRTC_IOS needs more delay for getSourceInfo()
+  int sleepTime = 150;
+  int sleepTime2 = 200;
+#else
+  int sleepTime = 100;
+  int sleepTime2 = 200;
+#endif
+
   VoEBase* voe_base_ = _mgr.BasePtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
+  VoEFile* file = _mgr.FilePtr();
+  VoENetwork* netw = _mgr.NetworkPtr();
 
 #ifdef _USE_EXTENDED_TRACE_
   TEST_MUSTPASS(VoiceEngine::SetTraceFile((output_path +
@@ -4572,6 +5009,259 @@
   TEST_MUSTPASS(voe_base_->Init());
 
   // ------------------------------------------------------------------------
+  // >> GetLocalIP
+  //
+  // State: VE initialized, no existing channels
+  TEST(GetLocalIP);
+  ANL();
+
+#ifdef WEBRTC_IOS
+  // Should fail
+  TEST_MUSTPASS(!netw->GetLocalIP(NULL, 0)); MARK();
+  TEST_ERROR(VE_FUNC_NOT_SUPPORTED);
+
+  ANL();
+  printf("NOTE: Local IP must be set in source code (line %d) \n",
+      __LINE__ + 1);
+  const char* localIP = "192.168.1.4";
+
+#else
+  // Must be big enough so that we can print an IPv6 address.
+  char localIP[256] = {0};
+
+  // invalid parameter
+  TEST_MUSTPASS(!netw->GetLocalIP(NULL));
+  MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+
+  // default function calls (IPv4)
+  TEST_MUSTPASS(netw->GetLocalIP(localIP));
+  MARK();
+  TEST_LOG("[local IPv4: %s]\n", localIP);
+  TEST_MUSTPASS(netw->GetLocalIP(localIP));
+  MARK();
+
+#if !defined(WEBRTC_MAC) && !defined(WEBRTC_ANDROID)
+  // default function calls (IPv6)
+  TEST_MUSTPASS(netw->GetLocalIP(localIP, true));
+  MARK();
+  TEST_LOG("[local IPv6: %s]\n", localIP);
+  TEST_MUSTPASS(netw->GetLocalIP(localIP, true));
+  MARK();
+#endif
+
+  // one last call to ensure that local
+  TEST_MUSTPASS(netw->GetLocalIP(localIP));
+  MARK();
+#endif
+
+  ANL();
+  AOK();
+  ANL();
+  ANL();
+
+  // >> end of GetLocalIP
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
+  // >> GetSourceInfo
+  //
+  // - VE initialized
+  // - no existing channels
+  TEST(GetSourceInfo);
+  ANL();
+
+  int rtpPort(0);
+  int rtcpPort(0);
+  char ipaddr[64] = { 0 };
+  ExtendedTestTransport* ptrTransport(NULL);
+
+  // call without valid channel
+  TEST_MUSTPASS(!netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // NULL as input string
+  TEST_MUSTPASS(!netw->GetSourceInfo(0, rtpPort, rtcpPort, NULL));
+  MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+
+  // call when external transport is enabled
+  ptrTransport = new ExtendedTestTransport(netw);
+  TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
+  TEST_MUSTPASS(!netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+  delete ptrTransport;
+
+  // call when external transport is disabled (no packet received yet)
+  TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 0);
+  TEST_MUSTPASS(rtcpPort != 0);
+  TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
+  // send and receive packets with default settings for a while
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime2); // does not guarantee RTCP
+
+  // verify remote parameters (exclude RTCP)
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 8000);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  // ensure that valid results are maintained after StopListen
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 8000);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  // verify that results are maintained after new call to SetLocalReceiver
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 8000);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  // STATE: not listening, not sending
+  // send and receive packets with other settings for a while
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 9005));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 9005, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+
+  // STATE: listening, sending
+
+  // verify new remote parameters
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 9005);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  // restart sending to and from local IP
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 9005, kVoEDefault, localIP));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 9005, localIP));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+
+  // verify new remote parameters
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 9005);
+  TEST_MUSTPASS(strcmp(ipaddr, localIP) != 0); // should not be "127.0.0.1"
+
+  // use non-default source port in outgoing packets
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 9005));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 9005, "127.0.0.1", 9010));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+
+  // verify new remote parameters
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 9010);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  // STATE: listening and sending using an extra local socket
+
+  // stop/start sending
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+
+  // verify that the unique source port is maintained for the extra socket
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 9010);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  // set new source port for outgoing packets (9010 -> 9020)
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 9005, "127.0.0.1", 9020));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+#ifdef WEBRTC_IOS
+  SleepMs(500); // Need extra pause for some reason
+#endif
+
+  // verify that the unique source port is set for the new extra socket
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 9020);
+  // STATE: listening and sending using an extra local socket
+
+  // remove extra send socket and restart call again
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0)); // delete channel => destroys the
+  // extra socket
+  TEST_MUSTPASS(voe_base_->CreateChannel()); // new channel uses one socket only
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000)); // use new port as well
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+
+  // verify that remote info is correct
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 8000);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  // STATE: listening and sending using shared socket
+
+  // use non-default source port in outgoing packets to create extra send
+  // socket
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 7000));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 7000, "127.0.0.1", 7010));
+  // RTP src is 7010 => RTCP src = 7011
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+  // verify new remote parameters
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 7010);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+
+  // check RTCP port as well (should be 7010 + 1 = 7011)
+  Sleep(8000, true);
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 7010);
+  TEST_MUSTPASS(rtcpPort != 7011);
+  TEST_MUSTPASS(strcmp(ipaddr, "127.0.0.1") != 0);
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+
+  ANL();
+  AOK();
+  ANL();
+  ANL();
+
+  // >> end of GetSourceInfo
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
   // >> SetExternalTransport
   //
   // - VE initialized
@@ -4581,54 +5271,127 @@
   TEST(SetExternalTransport);
   ANL();
 
-  ExtendedTestTransport* ptrTransport = new ExtendedTestTransport(voe_network);
+  ptrTransport = new ExtendedTestTransport(netw);
 
   // call without valid channel
-  TEST_MUSTPASS(!voe_network ->DeRegisterExternalTransport(0));
+  TEST_MUSTPASS(!netw->DeRegisterExternalTransport(0));
   MARK();
   TEST_ERROR(VE_CHANNEL_NOT_VALID);
 
   TEST_MUSTPASS(voe_base_->CreateChannel());
 
   // different valid call combinations
-  TEST_MUSTPASS(voe_network ->RegisterExternalTransport(0, *ptrTransport));
+  TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
   MARK();
-  TEST_MUSTPASS(voe_network ->DeRegisterExternalTransport(0));
+  TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
   MARK();
-  TEST_MUSTPASS(voe_network ->DeRegisterExternalTransport(0));
+  TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
   MARK();
-  TEST_MUSTPASS(voe_network ->RegisterExternalTransport(0, *ptrTransport));
+  TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
   MARK();
-  TEST_MUSTPASS(!voe_network ->RegisterExternalTransport(0, *ptrTransport));
+  TEST_MUSTPASS(!netw->RegisterExternalTransport(0, *ptrTransport));
   MARK(); // must deregister first
-  TEST_MUSTPASS(voe_network ->DeRegisterExternalTransport(0));
+  TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
   MARK();
 
   // STATE: external transport is disabled
+
+  // initialize sending and ensure that external transport can't be enabled
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 1234, "127.0.0.2"));
+  TEST_MUSTPASS(!netw->RegisterExternalTransport(0, *ptrTransport));
+  MARK();
+  TEST_ERROR(VE_SEND_SOCKETS_CONFLICT);
+
+  // restart channel to ensure that "initialized sender" state is cleared
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // initialize receiving and ensure that external transport can't be enabled
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 5678));
+  TEST_MUSTPASS(!netw->RegisterExternalTransport(0, *ptrTransport));
+  MARK();
+  TEST_ERROR(VE_RECEIVE_SOCKETS_CONFLICT);
+
+  // restart channel to ensure that "initialized receiver" state is cleared
   TEST_MUSTPASS(voe_base_->DeleteChannel(0));
   TEST_MUSTPASS(voe_base_->CreateChannel());
 
   // enable external transport and verify that "emulated loopback" works
-  TEST_MUSTPASS(voe_network ->RegisterExternalTransport(0, *ptrTransport));
+  TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
   MARK();
   TEST_MUSTPASS(voe_base_->StartSend(0)); // should only start recording
-  TEST_MUSTPASS(!voe_network ->RegisterExternalTransport(0, *ptrTransport));
+  TEST_MUSTPASS(!netw->RegisterExternalTransport(0, *ptrTransport));
   MARK(); // should fail
-  TEST_MUSTPASS(voe_network ->DeRegisterExternalTransport(0));
+  TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
   MARK();
-  TEST_MUSTPASS(voe_network ->RegisterExternalTransport(0, *ptrTransport));
+  TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
   MARK();
   Play(0, 2000, true, true); // play file as mic and verify loopback audio
-  TEST_MUSTPASS(voe_network ->DeRegisterExternalTransport(0));
+  TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
   MARK();
 
+  // STATE: external transport is disabled
+#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
+  int testError = VE_FUNC_NOT_SUPPORTED;
+#else
+  int testError = VE_EXTERNAL_TRANSPORT_ENABLED;
+#endif
+
+  // check all APIs that should fail when external transport is enabled
+  int DSCP, priority, serviceType, overrideDSCP, nBytes(0);
+  bool useSetSockopt, enabled;
+  TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
+  MARK();
+  TEST_MUSTPASS(!voe_base_->SetLocalReceiver(0, 12345));
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+  TEST_MUSTPASS(!voe_base_->GetLocalReceiver(0, rtpPort, rtcpPort, ipaddr));
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+  TEST_MUSTPASS(!voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+  TEST_MUSTPASS(!voe_base_->GetSendDestination(0, rtpPort, ipaddr, rtpPort,
+          rtcpPort));
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+  TEST_MUSTPASS(!netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+  TEST_MUSTPASS(!netw->EnableIPv6(0))
+  TEST_ERROR(testError);
+  TEST_MUSTPASS(netw->IPv6IsEnabled(0) != false)
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+  TEST_MUSTPASS(!netw->SetSourceFilter(0, 12345, 12346));
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+  TEST_MUSTPASS(!netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+
   // modified i VoE 3.4 (can be called also for external transport)
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StopReceive(0));
 
+#if (!defined(_WIN32) && !defined(WEBRTC_LINUX) && !defined(WEBRTC_MAC)) || \
+      defined(WEBRTC_EXTERNAL_TRANSPORT)
+  testError = VE_FUNC_NOT_SUPPORTED;
+#else
+  testError = VE_EXTERNAL_TRANSPORT_ENABLED;
+#endif
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 0));
+  TEST_ERROR(testError);
+  TEST_MUSTPASS(!netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
+  TEST_ERROR(testError);
+#if !defined(_WIN32) || defined(WEBRTC_EXTERNAL_TRANSPORT)
+  testError = VE_FUNC_NOT_SUPPORTED;
+#else
+  testError = VE_EXTERNAL_TRANSPORT_ENABLED;
+#endif
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, false, 0));
+  TEST_ERROR(testError);
+  TEST_MUSTPASS(!netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  TEST_ERROR(testError);
+  char dummy[1] = { 'a' };
+  TEST_MUSTPASS(!netw->SendUDPPacket(0, dummy, 1, nBytes));
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+
   // always disable external transport before deleting the Transport object;
   // will lead to crash for RTCP transmission otherwise
-  TEST_MUSTPASS(voe_network ->DeRegisterExternalTransport(0));
+  TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
   MARK();
   delete ptrTransport;
 
@@ -4643,6 +5406,350 @@
   // ------------------------------------------------------------------------
 
   // ------------------------------------------------------------------------
+  // >> EnableIPv6
+  //
+  // - VE initialized
+  // - no existing channels
+  // - no media
+  // - NOTE: set _ENABLE_IPV6_TESTS_ to include these tests
+  // - http://www.microsoft.com/resources/documentation/windows/xp/all/
+  //   proddocs/en-us/sag_ip_v6_pro_rt_enable.mspx?mfr=true
+  // >> ipv6 install
+  // >> ipv6 [-v] if [IfIndex]
+  // >> ping6 ::1
+  // >> ping6 fe80::1
+
+#ifdef _ENABLE_IPV6_TESTS_
+
+  TEST(EnableIPv6); ANL();
+
+  // call without valid channel
+  TEST_MUSTPASS(!netw->EnableIPv6(0)); MARK();
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // call with enabled external transport
+  ptrTransport = new ExtendedTestTransport(netw);
+  TEST_MUSTPASS(netw->RegisterExternalTransport(0, *ptrTransport));
+  TEST_MUSTPASS(!netw->EnableIPv6(0)); MARK();
+  TEST_ERROR(VE_EXTERNAL_TRANSPORT_ENABLED);
+  TEST_MUSTPASS(netw->DeRegisterExternalTransport(0));
+  delete ptrTransport;
+
+  // Test "locking" to IPv4
+  TEST_MUSTPASS(netw->IPv6IsEnabled(0)); MARK(); // After this call we cannot
+  // enable IPv6
+  TEST_MUSTPASS(!netw->EnableIPv6(0)); MARK(); // Should fail
+
+  // Check that IPv6 address is invalid
+  TEST_MUSTPASS(!voe_base_->SetSendDestination(0, 8000, "::1")); MARK(); // fail
+
+  // New channel
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // valid default call
+  TEST_MUSTPASS(netw->EnableIPv6(0)); MARK();
+  TEST_MUSTPASS(netw->GetLocalIP(localIP)); MARK(); // should still read IPv4
+  TEST_LOG("[local IPv4: %s]", localIP);
+
+  // ensure that Ipv6 is enabled
+  TEST_MUSTPASS(netw->IPv6IsEnabled(0) != true);
+
+  // check that IPv4 address is invalid
+  TEST_MUSTPASS(!voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
+  TEST_ERROR(VE_INVALID_IP_ADDRESS);
+
+  // verify usage of IPv6 loopback address
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
+  // IPv6 loopback address is 0:0:0:0:0:0:0:1
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "::1"));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(!netw->EnableIPv6(0)); MARK(); // Should fail
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  Play(0, 2000, true, true);
+  ANL();
+
+  // Restart channel
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  TEST_MUSTPASS(netw->EnableIPv6(0)); MARK();
+  // ensure that Ipv6 is enabled
+  TEST_MUSTPASS(netw->IPv6IsEnabled(0) != true);
+
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  // IPv6 loopback address is 0:0:0:0:0:0:0:1
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "::1"));
+  TEST_MUSTPASS(voe_base_->StartPlayout(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(), true,
+      true);
+  SleepMs(500); // ensure that we receieve some packets
+
+  // SetSourceFilter and GetSourceFilter
+  TEST(SetSourceFilter and GetSourceFilter for IPv6); ANL();
+  char sourceIp[64] =
+  { 0};
+  char filterIp[64] =
+  { 0};
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, sourceIp));
+  TEST_LOG("Source port: %d \n", rtpPort);
+  TEST_LOG("Source RTCP port: %d \n", rtcpPort);
+  TEST_LOG("Source IP: %s \n", sourceIp);
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
+  TEST_LOG("Filter port RTP: %d \n", rtpPort);
+  TEST_LOG("Filter port RTCP: %d \n", rtcpPort);
+  TEST_LOG("Filter IP: %s \n", filterIp);
+  TEST_MUSTPASS(0 != rtpPort);
+  TEST_MUSTPASS(0 != rtcpPort);
+  TEST_MUSTPASS(filterIp[0] != '\0');
+  TEST_LOG("Set filter IP to %s => should hear audio\n", sourceIp);
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, sourceIp));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
+  TEST_MUSTPASS(0 != rtpPort);
+  TEST_MUSTPASS(0 != rtcpPort);
+  TEST_MUSTPASS(_stricmp(filterIp, sourceIp));
+  SleepMs(1500);
+  TEST_LOG("Set filter IP to ::10:10:10 => should *not* hear audio\n");
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::10:10:10"));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
+  TEST_MUSTPASS(_stricmp(filterIp, "::10:10:10"));
+  SleepMs(1500);
+  TEST_LOG("Disable IP filter => should hear audio again\n");
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::0"));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
+  TEST_MUSTPASS(_stricmp(filterIp, "::"));
+  SleepMs(1500);
+  TEST_LOG("Set filter IP to ::10:10:10 => should *not* hear audio\n");
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::10:10:10"));
+  SleepMs(1500);
+  TEST_LOG("Disable IP filter => should hear audio again\n");
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
+  TEST_MUSTPASS(filterIp[0] != '\0');
+  SleepMs(1500);
+  TEST_LOG("Set filter IP to ::10:10:10 => should *not* hear audio\n");
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::10:10:10"));
+  SleepMs(1500);
+  TEST_LOG("Disable IP filter => should hear audio again\n");
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "::"));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, filterIp));
+  TEST_MUSTPASS(_stricmp(filterIp, "::"));
+  SleepMs(1500);
+
+  file->StopPlayingFileAsMicrophone(0);
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+
+#endif // #ifdef _ENABLE_IPV6_TESTS_
+  // >> end of EnableIPv6
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
+  // >> SetSourceFilter
+  //
+  // - VE initialized
+  // - no existing channels
+  // - no media
+  TEST(SetSourceFilter);
+  ANL();
+
+  // call without valid channel
+  TEST_MUSTPASS(!netw->SetSourceFilter(0, 12345));
+  MARK();
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // invalid parameters
+  TEST_MUSTPASS(!netw->SetSourceFilter(0, 65536));
+  MARK();
+  TEST_ERROR(VE_INVALID_PORT_NMBR);
+  TEST_MUSTPASS(!netw->SetSourceFilter(0, 12345, 65536));
+  MARK();
+  TEST_ERROR(VE_INVALID_PORT_NMBR);
+  TEST_MUSTPASS(!netw->SetSourceFilter(0, 12345, 12346, "300.300.300.300"));
+  MARK();
+  TEST_ERROR(VE_INVALID_IP_ADDRESS);
+
+  // STATE: RTP filter port is 12345, RTCP filter port is 12346
+
+  // disable all filters and ensure that media is received
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
+  MARK();
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2000, kVoEDefault, localIP));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2000, localIP));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  TEST_MUSTPASS(rtpPort != 2000);
+  TEST_MUSTPASS(rtcpPort != 2001);
+  TEST_MUSTPASS(strcmp(ipaddr, localIP) != 0);
+
+  // clear states and restart loopback session
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0)); // clear source info state
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // set RTP filter to port 2002 and verify that source 2000 is blocked
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 2002, 0, NULL));;
+  MARK();
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2000, kVoEDefault, localIP));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2000, localIP));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  TEST_MUSTPASS(rtpPort != 0);
+  TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
+
+  // ensure that received packets originates from 2002 and that they now pass
+  // the filter
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  // RTP source is 2002
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2002, kVoEDefault, localIP));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2002, localIP));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  TEST_MUSTPASS(rtpPort != 2002);
+  TEST_MUSTPASS(strcmp(ipaddr, localIP) != 0);
+
+  // clear states and restart loopback session
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0)); // clear source info state
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // set IP filter to local IP and verify that default loopback stream is
+  // blocked
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, localIP));;
+  MARK();
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2000));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2000, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  TEST_MUSTPASS(rtpPort != 0);
+  TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
+
+  // ensure that received packets originates from the local IP and that they
+  // now pass the filter
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  // should pass the filter
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 2000, kVoEDefault, localIP));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 2000, localIP));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  SleepMs(sleepTime);
+  TEST_MUSTPASS(netw->GetSourceInfo(0, rtpPort, rtcpPort, ipaddr));
+  TEST_MUSTPASS(rtpPort != 2000);
+  TEST_MUSTPASS(strcmp(ipaddr, localIP) != 0);
+
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+
+  // STATE: no active media, IP filter is active
+
+  // disable all filters
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));;
+  MARK();
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  TEST_MUSTPASS(rtpPort != 0);
+  TEST_MUSTPASS(rtcpPort != 0);
+  TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+  ANL();
+  AOK();
+  ANL();
+  ANL();
+
+  // >> end of SetSourceFilter
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
+  // >> GetSourceFilter
+  //
+  // - VE initialized
+  // - no existing channels
+  // - no media
+  TEST(GetSourceFilter);
+  ANL();
+
+  // call without valid channel
+  TEST_MUSTPASS(!netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // invalid input parameters
+  TEST_MUSTPASS(!netw->GetSourceFilter(0, rtpPort, rtcpPort, NULL));
+  MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+
+  // valid call without any filter set
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 0);
+  TEST_MUSTPASS(rtcpPort != 0);
+  TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
+
+  // STATE: no active media and no enabled filters
+
+  // set different filters and verify that they "bite"
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 54321, 0, NULL));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 54321);
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtpPort != 0);
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 15425, NULL));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtcpPort != 15425);
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(rtcpPort != 0);
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "192.168.199.19"));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(strcmp(ipaddr, "192.168.199.19") != 0);
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, "0.0.0.0"));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(strcmp(ipaddr, "0.0.0.0") != 0);
+  TEST_MUSTPASS(netw->SetSourceFilter(0, 0, 0, NULL));
+  TEST_MUSTPASS(netw->GetSourceFilter(0, rtpPort, rtcpPort, ipaddr));
+  MARK();
+  TEST_MUSTPASS(strcmp(ipaddr, "") != 0);
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+  ANL();
+  AOK();
+  ANL();
+  ANL();
+
+  // >> end of GetSourceFilter
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
   // >> RegisterDeadOrAliveObserver
   // >> DeRegisterDeadOrAliveObserver
   //
@@ -4655,24 +5762,24 @@
   ANL();
 
   // call without valid channel
-  TEST_MUSTPASS(!voe_network ->RegisterDeadOrAliveObserver(0, *this));
+  TEST_MUSTPASS(!netw->RegisterDeadOrAliveObserver(0, *this));
   MARK();
   TEST_ERROR(VE_CHANNEL_NOT_VALID);
 
   TEST_MUSTPASS(voe_base_->CreateChannel());
 
-  TEST_MUSTPASS(voe_network ->RegisterDeadOrAliveObserver(0, *this));
+  TEST_MUSTPASS(netw->RegisterDeadOrAliveObserver(0, *this));
   MARK();
-  TEST_MUSTPASS(!voe_network ->RegisterDeadOrAliveObserver(0, *this));
+  TEST_MUSTPASS(!netw->RegisterDeadOrAliveObserver(0, *this));
   MARK(); // already registered
   TEST_ERROR(VE_INVALID_OPERATION);
-  TEST_MUSTPASS(voe_network ->DeRegisterDeadOrAliveObserver(0));
+  TEST_MUSTPASS(netw->DeRegisterDeadOrAliveObserver(0));
   MARK();
-  TEST_MUSTPASS(voe_network ->DeRegisterDeadOrAliveObserver(0));
+  TEST_MUSTPASS(netw->DeRegisterDeadOrAliveObserver(0));
   MARK(); // OK to do it again
-  TEST_MUSTPASS(voe_network ->RegisterDeadOrAliveObserver(0, *this));
+  TEST_MUSTPASS(netw->RegisterDeadOrAliveObserver(0, *this));
   MARK();
-  TEST_MUSTPASS(voe_network ->DeRegisterDeadOrAliveObserver(0));
+  TEST_MUSTPASS(netw->DeRegisterDeadOrAliveObserver(0));
   MARK();
 
   TEST_MUSTPASS(voe_base_->DeleteChannel(0));
@@ -4691,43 +5798,39 @@
   // - no media
 
   // call without valid channel
-  TEST_MUSTPASS(!voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
+  TEST_MUSTPASS(!netw->SetPeriodicDeadOrAliveStatus(0, false));
   MARK();
   TEST_ERROR(VE_CHANNEL_NOT_VALID);
 
   TEST_MUSTPASS(voe_base_->CreateChannel());
 
   // Invalid paramters
-  TEST_MUSTPASS(!voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 0));
+  TEST_MUSTPASS(!netw->SetPeriodicDeadOrAliveStatus(0, true, 0));
   MARK();
   TEST_ERROR(VE_INVALID_ARGUMENT);
-  TEST_MUSTPASS(!voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 151));
+  TEST_MUSTPASS(!netw->SetPeriodicDeadOrAliveStatus(0, true, 151));
   MARK();
   TEST_ERROR(VE_INVALID_ARGUMENT);
-  TEST_MUSTPASS(!voe_network ->SetPeriodicDeadOrAliveStatus(1, true, 10));
+  TEST_MUSTPASS(!netw->SetPeriodicDeadOrAliveStatus(1, true, 10));
   MARK();
   TEST_ERROR(VE_CHANNEL_NOT_VALID);
 
   int sampleTime(0);
-  bool enabled;
 
   // Valid parameters
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 1));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 1));
   MARK();
-  TEST_MUSTPASS(
-      voe_network ->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
+  TEST_MUSTPASS(netw->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
   TEST_MUSTPASS(enabled != true);
   TEST_MUSTPASS(sampleTime != 1);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 150));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 150));
   MARK();
-  TEST_MUSTPASS(
-      voe_network ->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
+  TEST_MUSTPASS(netw->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
   TEST_MUSTPASS(enabled != true);
   TEST_MUSTPASS(sampleTime != 150);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, false));
   MARK();
-  TEST_MUSTPASS(
-      voe_network ->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
+  TEST_MUSTPASS(netw->GetPeriodicDeadOrAliveStatus(0, enabled, sampleTime));
   TEST_MUSTPASS(enabled != false);
   TEST_MUSTPASS(sampleTime != 150); // ensure last set time isnt modified
 
@@ -4736,25 +5839,25 @@
   // STATE: full duplex media is active
 
   // test the dead-or-alive mechanism
-  TEST_MUSTPASS(voe_network ->RegisterDeadOrAliveObserver(0, *this));
+  TEST_MUSTPASS(netw->RegisterDeadOrAliveObserver(0, *this));
   MARK();
   TEST_LOG("\nVerify that Alive callbacks are received (dT=2sec): ");
   fflush(NULL);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 2));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 2));
   SleepMs(6000);
   TEST_LOG("\nChange dT to 1 second: ");
   fflush(NULL);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 1));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 1));
   SleepMs(6000);
   TEST_LOG("\nDisable dead-or-alive callbacks: ");
   fflush(NULL);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, false));
   SleepMs(6000);
   TEST_LOG("\nStop sending and enable callbacks again.\n");
   TEST_LOG("Verify that Dead callbacks are received (dT=2sec): ");
   fflush(NULL);
   TEST_MUSTPASS(voe_base_->StopSend(0));
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, true, 2));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, true, 2));
   SleepMs(6000);
   TEST_MUSTPASS(voe_base_->StartSend(0));
   TEST_LOG("\nRestart sending.\n");
@@ -4763,8 +5866,8 @@
   SleepMs(6000);
   TEST_LOG("\nDisable dead-or-alive callbacks.");
   fflush(NULL);
-  TEST_MUSTPASS(voe_network ->SetPeriodicDeadOrAliveStatus(0, false));
-  TEST_MUSTPASS(voe_network ->DeRegisterDeadOrAliveObserver(0));
+  TEST_MUSTPASS(netw->SetPeriodicDeadOrAliveStatus(0, false));
+  TEST_MUSTPASS(netw->DeRegisterDeadOrAliveObserver(0));
   MARK();
 
   StopMedia(0);
@@ -4795,47 +5898,47 @@
   ANL();
 
   // call without existing valid channel
-  TEST_MUSTPASS(!voe_network ->SetPacketTimeoutNotification(0, false));
+  TEST_MUSTPASS(!netw->SetPacketTimeoutNotification(0, false));
   MARK();
   TEST_ERROR(VE_CHANNEL_NOT_VALID);
 
   TEST_MUSTPASS(voe_base_->CreateChannel());
 
   // invalid function calls
-  TEST_MUSTPASS(!voe_network ->SetPacketTimeoutNotification(0, true, 0));
+  TEST_MUSTPASS(!netw->SetPacketTimeoutNotification(0, true, 0));
   MARK();
   TEST_ERROR(VE_INVALID_ARGUMENT);
-  TEST_MUSTPASS(!voe_network ->SetPacketTimeoutNotification(0, true, 151));
+  TEST_MUSTPASS(!netw->SetPacketTimeoutNotification(0, true, 151));
   MARK();
   TEST_ERROR(VE_INVALID_ARGUMENT);
 
   // valid function calls (no active media)
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, true, 2));
+  TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, true, 2));
   MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled, timeOut));
+  TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
   MARK();
   TEST_MUSTPASS(enabled != true);
   TEST_MUSTPASS(timeOut != 2);
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, false));
+  TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, false));
   MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled, timeOut));
+  TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
   MARK();
   TEST_MUSTPASS(enabled != false);
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, true, 10));
+  TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, true, 10));
   MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled, timeOut));
+  TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
   MARK();
   TEST_MUSTPASS(enabled != true);
   TEST_MUSTPASS(timeOut != 10);
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, true, 2));
+  TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, true, 2));
   MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled, timeOut));
+  TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
   MARK();
   TEST_MUSTPASS(enabled != true);
   TEST_MUSTPASS(timeOut != 2);
-  TEST_MUSTPASS(voe_network ->SetPacketTimeoutNotification(0, false));
+  TEST_MUSTPASS(netw->SetPacketTimeoutNotification(0, false));
   MARK();
-  TEST_MUSTPASS(voe_network ->GetPacketTimeoutNotification(0, enabled, timeOut));
+  TEST_MUSTPASS(netw->GetPacketTimeoutNotification(0, enabled, timeOut));
   MARK();
   TEST_MUSTPASS(enabled != false);
 
@@ -4844,18 +5947,521 @@
   AOK();
   ANL();
   ANL();
-  return 0;
-}
+
   // >> end of SetPacketTimeoutNotification
   // ------------------------------------------------------------------------
 
+  // ------------------------------------------------------------------------
+  // >> SendUDPPacket
+  //
+  // - VE initialized
+  // - no existing channels
+  // - no media
+
+
+  // >> end of SendUDPPacket
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
+  // >> SetSendTOS
+  //
+  // - VE initialized
+  // - no existing channels
+  // - no media
+  TEST(SetSendTOS);
+  ANL();
+#if defined(_WIN32) || defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
+
+  // call without existing valid channel
+
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 0)); MARK();
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // trivial invalid function calls
+  TEST_MUSTPASS(!netw->SetSendTOS(0, -1)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 64)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 1, -2)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 1, 8)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 1)); MARK();
+  TEST_ERROR(VE_SOCKET_ERROR); // must create sockets first
+
+#ifdef _WIN32
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 3000));
+
+  // enable ToS using SetSockopt (should work without local binding)
+  TEST_MUSTPASS(netw->SetSendTOS(0, 1, -1, true)); MARK();
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt)); MARK();
+  TEST_MUSTPASS(DSCP != 1);
+  TEST_MUSTPASS(priority != 0);
+  TEST_MUSTPASS(useSetSockopt != true);
+
+  // try to disable SetSockopt while ToS is enabled (should fail)
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 1, -1, false)); MARK();
+  TEST_ERROR(VE_TOS_INVALID); // must disable ToS before enabling SetSockopt
+
+  // disable ToS to be able to stop using SetSockopt
+  TEST_MUSTPASS(netw->SetSendTOS(0, 0, -1, true)); MARK(); // disable ToS
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt)); MARK();
+  TEST_MUSTPASS(DSCP != 0);
+  TEST_MUSTPASS(priority != 0);
+  TEST_MUSTPASS(useSetSockopt != true);
+
+  // to use the "non-SetSockopt" method, local binding is required,
+  // trying without it should fail
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 1, -1, false)); MARK();
+  TEST_ERROR(VE_TOS_ERROR); // must bind to local IP first
+
+  // bind to local IP and try again (should work this time)
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345, kVoEDefault, localIP));
+  TEST_LOG("\nThis test needs to be run as administrator\n");
+  TEST_MUSTPASS(netw->SetSendTOS(0, 1, -1, false)); MARK();
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt)); MARK();
+  TEST_MUSTPASS(DSCP != 1);
+  TEST_MUSTPASS(priority != 0);
+  TEST_MUSTPASS(useSetSockopt != false);
+
+  // STATE: binded to local IP, local port is 12345 and DSCP is 1 (not using
+  // SetSockopt)
+
+  // verify loopback audio with the current settings
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, localIP));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  Play(0, 2000, true, true); // file should be played out here...
+
+#ifdef _SEND_TO_REMOTE_IP_
+  // Send to remote destination and verify the DSCP using Wireshark.
+  // Use filter ip.src == "RemoteIP".
+  TEST_LOG("\nUse Wireshark and verify a correctly received DSCP at the "
+      "remote side!\n");
+  TEST_LOG("Sending approx. 5 packets to %s:%d for each DSCP below:\n",
+      RemoteIP, RemotePort);
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, RemotePort, RemoteIP));
+  TEST_LOG("  DSCP is set to 0x%02x\n", 1);
+  SleepMs(100);
+
+  // Change the DSCP while sending is active and verify on remote side.
+  TEST_MUSTPASS(netw->SetSendTOS(0, 2));
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
+  TEST_LOG("  DSCP is set to 0x%02x\n", DSCP);
+  SleepMs(100);
+
+  // Change the DSCP while sending is active and verify on remote side.
+  TEST_MUSTPASS(netw->SetSendTOS(0, 63));
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
+  TEST_LOG("  DSCP is set to 0x%02x\n", DSCP);
+  SleepMs(100);
+
+  // stop and resume sending
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
+  TEST_LOG("  DSCP is set to 0x%02x\n", DSCP);
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(netw->SetSendTOS(0, 0));
+#endif // _SEND_TO_REMOTE_IP_
+  // Windows priority tests (priority cannot be set using setsockopt on Win)
+  TEST_LOG("Testing priority\n");
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, localIP));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 0, 3, true)); // Should fail
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(netw->SetSendTOS(0, 0, 3, false));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  Play(0, 2000, true, true); // file should be played out here...
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(netw->SetSendTOS(0, 1, 3, false));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  Play(0, 2000, true, true); // file should be played out here...
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+#endif // _WIN32
+  // STATE: no media, disabled ToS, no defined receiver
+
+  // Repeat tests above but using setsockopt() this time.
+  // Binding to local IP should not be required.
+
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345, kVoEDefault));
+  TEST_MUSTPASS(netw->SetSendTOS(0, 10, -1, true)); MARK();
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt)); MARK();
+  TEST_MUSTPASS(DSCP != 10);
+  TEST_MUSTPASS(priority != 0);
+  TEST_MUSTPASS(useSetSockopt != true);
+
+  // STATE: *not* binded to local IP, local port is 12345 and DSCP is 10
+  // (using SetSockopt)
+
+  // verify loopback audio with the current settings
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  Play(0, 2000, true, true); // file should be played out here...
+
+#ifdef _SEND_TO_REMOTE_IP_
+  // Send to remote destination and verify the DSCP using Wireshark.
+  // Use filter ip.src == "RemoteIP".
+  TEST_LOG("\nUse Wireshark and verify a correctly received DSCP at the"
+      " remote side!\n");
+  TEST_LOG("Sending approx. 5 packets to %s:%d for each DSCP below:\n",
+      RemoteIP, RemotePort);
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, RemotePort, RemoteIP));
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
+  TEST_LOG("  DSCP is set to 0x%02x (setsockopt)\n", DSCP);
+  SleepMs(100);
+
+  // Change the DSCP while sending is active and verify on remote side.
+  TEST_MUSTPASS(netw->SetSendTOS(0, 20, -1, true)); // use setsockopt()
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
+  TEST_LOG("  DSCP is set to 0x%02x (setsockopt)\n", DSCP);
+  SleepMs(100);
+
+  // Change the DSCP while sending is active and verify on remote side.
+  TEST_MUSTPASS(netw->SetSendTOS(0, 61, -1, true)); // use setsockopt()
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
+  TEST_LOG("  DSCP is set to 0x%02x (setsockopt)\n", DSCP);
+  SleepMs(100);
+
+  // stop and resume sending
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  TEST_MUSTPASS(netw->GetSendTOS(0, DSCP, priority, useSetSockopt));
+  TEST_LOG("  DSCP is set to 0x%02x (setsockopt)\n", DSCP);
+  SleepMs(100);
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(netw->SetSendTOS(0, 0, -1, true));
+#endif // _SEND_TO_REMOTE_IP_
+#if defined(WEBRTC_LINUX)
+  // Linux priority tests (using setsockopt)
+  TEST_LOG("Testing priority\n");
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, localIP));
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(netw->SetSendTOS(0, 0, 3, true));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  Play(0, 2000, true, true); // file should be played out here...
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(netw->SetSendTOS(0, 1, 3, true));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  Play(0, 2000, true, true); // file should be played out here...
+#endif // #if defined(WEBRTC_LINUX)
+#if !defined(_WIN32) && !defined(WEBRTC_LINUX)
+  // Fail tests for other than Wind and Linux
+  TEST_MUSTPASS(!netw->SetSendTOS(0, 0, 3, false)); // Should fail
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+#endif // #if !defined(_WIN32) && !defined(WEBRTC_LINUX)
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+  ANL(); AOK(); ANL(); ANL();
+
+  // END #if defined(_WIN32) || defined(WEBRTC_MAC) || defined(WEBRTC_LINUX)
+#else
+  TEST_LOG("Skipping ToS tests -  _WIN32, LINUX, MAC is not defined or "
+    "WEBRTC_ANDROID is defined");
+#endif
+
+  // >> end of SetSendTOS
+  // ------------------------------------------------------------------------
+
+  // ------------------------------------------------------------------------
+  // >> SetSendGQoS (Windows only)
+  //
+  // - VE initialized
+  // - no existing channels
+  // - no media
+  //
+  // From qos.h:
+  //
+  //  #define SERVICETYPE_NOTRAFFIC               0x00000000
+  //  #define SERVICETYPE_BESTEFFORT              0x00000001 (*)
+  //  #define SERVICETYPE_CONTROLLEDLOAD          0x00000002 (*)
+  //  #define SERVICETYPE_GUARANTEED              0x00000003 (*)
+  //  #define SERVICETYPE_NETWORK_UNAVAILABLE     0x00000004
+  //  #define SERVICETYPE_GENERAL_INFORMATION     0x00000005
+  //  #define SERVICETYPE_NOCHANGE                0x00000006
+  //  #define SERVICETYPE_NONCONFORMING           0x00000009
+  //  #define SERVICETYPE_NETWORK_CONTROL         0x0000000A
+  //  #define SERVICETYPE_QUALITATIVE             0x0000000D (*)
+  //
+  //  #define SERVICE_BESTEFFORT                  0x80010000
+  //  #define SERVICE_CONTROLLEDLOAD              0x80020000
+  //  #define SERVICE_GUARANTEED                  0x80040000
+  //  #define SERVICE_QUALITATIVE                 0x80200000
+  //
+  //  (*) supported in WEBRTC VoE
+  TEST(SetSendGQoS);
+  ANL();
+#ifdef _WIN32
+
+  // call without existing valid channel
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, false, 0)); MARK();
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+
+  TEST_MUSTPASS(voe_base_->CreateChannel());
+
+  // supported service type but no sockets
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT)); MARK();
+  TEST_ERROR(VE_SOCKETS_NOT_INITED);
+
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+
+  // supported service type but sender is not initialized
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT)); MARK();
+  TEST_ERROR(VE_DESTINATION_NOT_INITED);
+
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
+
+  // invalid service types
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NOTRAFFIC)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NETWORK_UNAVAILABLE));
+  MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_GENERAL_INFORMATION));
+  MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NOCHANGE)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NONCONFORMING));
+  MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_NETWORK_CONTROL));
+  MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICE_BESTEFFORT)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICE_CONTROLLEDLOAD)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICE_GUARANTEED)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICE_QUALITATIVE)); MARK();
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+
+  // Is ToS enabled here?
+
+  // Settings which don't require binding to local IP
+
+  // set SERVICETYPE_BESTEFFORT
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT)); MARK();
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  MARK();
+  TEST_MUSTPASS(enabled != true);
+  TEST_MUSTPASS(serviceType != SERVICETYPE_BESTEFFORT);
+  TEST_MUSTPASS(overrideDSCP != false);
+
+  // set SERVICETYPE_CONTROLLEDLOAD
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_CONTROLLEDLOAD));
+  MARK();
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  MARK();
+  TEST_MUSTPASS(enabled != true);
+  TEST_MUSTPASS(serviceType != SERVICETYPE_CONTROLLEDLOAD);
+  TEST_MUSTPASS(overrideDSCP != false);
+
+  // set SERVICETYPE_GUARANTEED
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_GUARANTEED)); MARK();
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  MARK();
+  TEST_MUSTPASS(enabled != true);
+  TEST_MUSTPASS(serviceType != SERVICETYPE_GUARANTEED);
+  TEST_MUSTPASS(overrideDSCP != false);
+
+  // set SERVICETYPE_QUALITATIVE
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_QUALITATIVE)); MARK();
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  MARK();
+  TEST_MUSTPASS(enabled != true);
+  TEST_MUSTPASS(serviceType != SERVICETYPE_QUALITATIVE);
+  TEST_MUSTPASS(overrideDSCP != false);
+
+  // disable GQoS
+  TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0)); MARK();
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  MARK();
+  TEST_MUSTPASS(enabled != false);
+  TEST_MUSTPASS(serviceType != SERVICETYPE_QUALITATIVE);
+  TEST_MUSTPASS(overrideDSCP != false);
+
+  // STATE: diabled QGoS, sockets exists, sending side is initialized, no media
+
+  // Loopback tests using the four different GQoS settings
+
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT)); MARK();
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  ANL();
+  TEST_LOG("[SERVICETYPE_BESTEFFORT]");
+  Play(0, 2000, true, true); // file should be played out here...
+
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_CONTROLLEDLOAD)); MARK();
+  ANL();
+  TEST_LOG("[SERVICETYPE_CONTROLLEDLOAD]");
+  Play(0, 2000, true, true); // file should be played out here...
+
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_GUARANTEED)); MARK();
+  ANL();
+  TEST_LOG("[SERVICETYPE_GUARANTEED]");
+  Play(0, 2000, true, true); // file should be played out here...
+
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_QUALITATIVE)); MARK();
+  ANL();
+  TEST_LOG("[SERVICETYPE_QUALITATIVE]");
+  Play(0, 2000, true, true); // file should be played out here...
+
+#ifdef _SEND_TO_REMOTE_IP_
+  // Send to remote destination and verify the DSCP mapping using Wireshark.
+  // Use filter ip.src == "RemoteIP".
+
+  // Modify the send destination on the fly
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, RemotePort, RemoteIP));
+
+  TEST_LOG("\nUse Wireshark and verify a correctly received DSCP mapping at"
+      " the remote side!\n");
+  TEST_LOG("Sending approx. 5 packets to %s:%d for each GQoS setting below:\n",
+      RemoteIP, RemotePort);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT));
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  TEST_LOG("  serviceType is set to SERVICETYPE_BESTEFFORT (0x%02x), should "
+      "be mapped to DSCP = 0x00\n", serviceType);
+  SleepMs(100);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_CONTROLLEDLOAD));
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  TEST_LOG("  serviceType is set to SERVICETYPE_CONTROLLEDLOAD (0x%02x), "
+      "should be mapped to DSCP = 0x18\n", serviceType);
+  SleepMs(100);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0));
+  TEST_LOG("  QoS is disabled, should give DSCP = 0x%02x\n", 0);
+  SleepMs(100);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_GUARANTEED));
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  TEST_LOG("  serviceType is set to SERVICETYPE_GUARANTEED (0x%02x), should "
+      "be mapped to DSCP = 0x28\n", serviceType);
+  SleepMs(100);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0));
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_QUALITATIVE));
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  TEST_LOG("  serviceType is set to SERVICETYPE_QUALITATIVE (0x%02x), should"
+      " be mapped to DSCP = 0x00\n", serviceType);
+  SleepMs(100);
+#endif // _SEND_TO_REMOTE_IP_
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+
+  // STATE: sockets exists, sending side is initialized, no media
+
+  // Repeat test above but this time using overrideDSCP.
+
+  // Some initial loopack tests.
+  // NOTE - override DSCP requres binding to local IP.
+
+  // should not work since QoS is enabled
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 3));
+  MARK();
+  TEST_ERROR(VE_TOS_GQOS_CONFLICT);
+
+  // disble QoS and try to override again (should fail again since local
+  // binding is not done yet)
+  TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0));
+  TEST_MUSTPASS(!netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 3));
+  MARK();
+  TEST_ERROR(VE_GQOS_ERROR);
+
+  // make proper settings and try again (should work this time)
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345, kVoEDefault, localIP));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, localIP));
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 3));
+  MARK();
+
+  // Now, let's try some loopback tests using override DSCP
+
+  TEST_MUSTPASS(voe_base_->StartReceive(0));
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  ANL();
+  TEST_LOG("[overrideDSCP=3]");
+  Play(0, 2000, true, true); // file should be played out here...
+
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 17));
+  MARK();
+  ANL();
+  TEST_LOG("[overrideDSCP=17]");
+  Play(0, 2000, true, true); // file should be played out here...
+
+  // And finally, send to remote side as well to verify that the new mapping
+  // works as it should.
+
+#ifdef _SEND_TO_REMOTE_IP_
+  // Modify the send destination on the fly
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, RemotePort, RemoteIP));
+
+  TEST_LOG("\nUse Wireshark and verify a correctly received DSCP mapping at"
+      " the remote side!\n");
+  TEST_LOG("Sending approx. 5 packets to %s:%d for each GQoS setting below:\n",
+      RemoteIP, RemotePort);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 18));
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  TEST_LOG("  serviceType is set to SERVICETYPE_BESTEFFORT, should be "
+      "overrided to DSCP = 0x%02x\n", overrideDSCP);
+  SleepMs(100);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 62));
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  TEST_LOG("  serviceType is set to SERVICETYPE_BESTEFFORT, should be "
+      "overrided to DSCP = 0x%02x\n", overrideDSCP);
+  SleepMs(100);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 32));
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  TEST_LOG("  serviceType is set to SERVICETYPE_BESTEFFORT, should be "
+      "overrided to DSCP = 0x%02x\n", overrideDSCP);
+  SleepMs(100);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, true, SERVICETYPE_BESTEFFORT, 1));
+  TEST_MUSTPASS(netw->GetSendGQoS(0, enabled, serviceType, overrideDSCP));
+  TEST_LOG("  serviceType is set to SERVICETYPE_BESTEFFORT, should be "
+      "overrided to DSCP = 0x%02x\n", overrideDSCP);
+  SleepMs(100);
+  TEST_MUSTPASS(netw->SetSendGQoS(0, false, 0));
+  TEST_LOG("  QoS is disabled, should give DSCP = 0x%02x\n", 0);
+  SleepMs(100);
+#endif // _SEND_TO_REMOTE_IP_
+  TEST_MUSTPASS(voe_base_->StopReceive(0));
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+
+  TEST_MUSTPASS(voe_base_->DeleteChannel(0));
+  ANL(); AOK(); ANL(); ANL();
+
+#else
+  TEST_LOG("Skipping GQoS tests - _WIN32 is not defined");
+#endif  // #ifdef _WIN32
+  // >> end of SetSendGQoS
+  // ------------------------------------------------------------------------
+
+    if (file) {
+    file->StopPlayingFileAsMicrophone(0);
+  }
+  voe_base_->StopSend(0);
+  voe_base_->StopPlayout(0);
+  voe_base_->StopReceive(0);
+  voe_base_->DeleteChannel(0);
+  voe_base_->Terminate();
+
+  ANL();
+  AOK();
+  return 0;
+}
+
 // ----------------------------------------------------------------------------
 //  VoEExtendedTest::TestRTP_RTCP
 // ----------------------------------------------------------------------------
 
 // Used to validate packets during the RTP audio level indication test.
 class RTPAudioTransport: public Transport {
- public:
+public:
+
   RTPAudioTransport() :
     mute_(false) {
   }
@@ -4906,6 +6512,7 @@
       assert(vad == 0 || vad == 1);
       assert(level >= 0 && level <= 127);
     }
+
     return 0;
   }
 
@@ -4914,7 +6521,7 @@
     return 0;
   }
 
- private:
+private:
   bool mute_;
 };
 
@@ -4951,13 +6558,8 @@
 
   TEST_MUSTPASS(voe_base_->Init());
   TEST_MUSTPASS(voe_base_->CreateChannel());
- 
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(network, 0));
-
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
-
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
@@ -5060,12 +6662,8 @@
   TEST_MUSTPASS(voe_base_->DeleteChannel(1));
 
   TEST_MUSTPASS(voe_base_->CreateChannel());
-  
-  voice_channel_transport.reset(new VoiceChannelTransport(network, 0));
-
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
-  
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
@@ -5074,7 +6672,7 @@
   ANL();
 
   // ------------------------------------------------------------------------
-  // >> SetLocalSSRC
+  // >> InsertExtraRTPPacket
 
   int i(0);
 
@@ -5092,6 +6690,58 @@
           true, true));
 
   // ------------------------------------------------------------------------
+  // >> InsertExtraRTPPacket
+  TEST(InsertExtraRTPPacket);
+  ANL();
+
+  const char payloadData[8] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' };
+
+  TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(-1, 0, false,
+          payloadData, 8));
+  MARK(); // invalid channel
+  TEST_ERROR(VE_CHANNEL_NOT_VALID);
+  TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, -1, false,
+          payloadData, 8));
+  MARK(); // invalid payload type
+  TEST_ERROR(VE_INVALID_PLTYPE);
+  TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, 128, false,
+          payloadData, 8));
+  MARK(); // invalid payload type
+  TEST_ERROR(VE_INVALID_PLTYPE);
+  TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, 99, false,
+          NULL, 8));
+    MARK(); // invalid pointer
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, 99, false,
+          payloadData, 1500-28+1));
+  MARK(); // invalid size
+  TEST_ERROR(VE_INVALID_ARGUMENT);
+  TEST_MUSTPASS(voe_base_->StopSend(0));
+  TEST_MUSTPASS(-1 != rtp_rtcp->InsertExtraRTPPacket(0, 99, false,
+          payloadData, 8));
+  MARK(); // not sending
+  TEST_ERROR(VE_NOT_SENDING);
+  TEST_MUSTPASS(voe_base_->StartSend(0));
+  TEST_MUSTPASS(file->StartPlayingFileAsMicrophone(0, _mgr.AudioFilename(),
+          true, true));
+
+  SleepMs(1000);
+  for (int p = 0; p < 128; p++) {
+    TEST_MUSTPASS(rtp_rtcp->InsertExtraRTPPacket(0, p, false,
+            payloadData, 8));
+    MARK();
+    TEST_MUSTPASS(rtp_rtcp->InsertExtraRTPPacket(0, p, true,
+            payloadData, 8));
+    MARK();
+  }
+
+  // Ensure we have sent all extra packets before we move forward to avoid
+  //incorrect error code
+  SleepMs(1000);
+
+  ANL();
+
+  // ------------------------------------------------------------------------
   // >> RTP dump APIs
   TEST(Start/StopRtpDump);
   ANL();
@@ -5229,12 +6879,8 @@
   SleepMs(100);
 
   TEST_MUSTPASS(voe_base_->CreateChannel());
-  
-  voice_channel_transport.reset(new VoiceChannelTransport(network, 0));
-
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
-
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
@@ -5480,12 +7126,8 @@
   // We have to re-register the audio codec payload type as stopReceive will
   // clean the database
   TEST_MUSTPASS(codec->SetRecPayloadType(0, cinst));
-  
-  voice_channel_transport.reset(new VoiceChannelTransport(network, 0));
-
-  voice_channel_transport->SetSendDestination("127.0.0.1", 8000);
-  voice_channel_transport->SetLocalReceiver(8000);
-
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 8000));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 8000, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
@@ -5521,7 +7163,6 @@
 
   VoEBase* voe_base_ = _mgr.BasePtr();
   VoEVideoSync* vsync = _mgr.VideoSyncPtr();
-  VoENetwork* network = _mgr.NetworkPtr();
 
   // check if this interface is supported
   if (!vsync)
@@ -5545,13 +7186,8 @@
 
   TEST_MUSTPASS(voe_base_->Init());
   TEST_MUSTPASS(voe_base_->CreateChannel());
-
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(network, 0));
-
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
-
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
@@ -5629,7 +7265,6 @@
 
   VoEBase* voe_base_ = _mgr.BasePtr();
   VoEVolumeControl* volume = _mgr.VolumeControlPtr();
-  VoENetwork* network = _mgr.NetworkPtr();
 #ifdef _TEST_FILE_
   VoEFile* file = _mgr.FilePtr();
 #endif
@@ -5661,10 +7296,8 @@
   TEST_MUSTPASS(hardware->SetPlayoutDevice(0));
 #endif
 #endif
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(network, 0));
-  voice_channel_transport->SetSendDestination("127.0.0.1", 12345);
-  voice_channel_transport->SetLocalReceiver(12345);
+  TEST_MUSTPASS(voe_base_->SetLocalReceiver(0, 12345));
+  TEST_MUSTPASS(voe_base_->SetSendDestination(0, 12345, "127.0.0.1"));
   TEST_MUSTPASS(voe_base_->StartReceive(0));
   TEST_MUSTPASS(voe_base_->StartPlayout(0));
   TEST_MUSTPASS(voe_base_->StartSend(0));
diff --git a/voice_engine/test/auto_test/voe_extended_test.h b/voice_engine/test/auto_test/voe_extended_test.h
index af549f8..c685d88 100644
--- a/voice_engine/test/auto_test/voe_extended_test.h
+++ b/voice_engine/test/auto_test/voe_extended_test.h
@@ -12,14 +12,7 @@
 #define WEBRTC_VOICE_ENGINE_VOE_EXTENDED_TEST_H
 
 #include "voe_standard_test.h"
-#include "webrtc/modules/audio_device/include/audio_device.h"
-#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
-#include "webrtc/system_wrappers/interface/event_wrapper.h"
-#include "webrtc/system_wrappers/interface/ref_count.h"
-#include "webrtc/system_wrappers/interface/sleep.h"
-#include "webrtc/system_wrappers/interface/thread_wrapper.h"
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
+#include "modules/audio_device/include/audio_device.h"
 
 namespace voetest {
 
@@ -432,22 +425,20 @@
   int TestRTP_RTCP();
   int TestVideoSync();
   int TestVolumeControl();
-
+ public:
   int ErrorCode() const {
     return _errCode;
   }
   void ClearErrorCode() {
     _errCode = 0;
   }
-
  protected:
   // from VoiceEngineObserver
   void CallbackOnError(const int errCode, const int channel);
   void CallbackOnTrace(const TraceLevel level, const char* message, const int length);
-
+ protected:
   // from VoEConnectionObserver
   void OnPeriodicDeadOrAlive(const int channel, const bool alive);
-
  private:
   void Play(int channel, unsigned int timeMillisec, bool addFileAsMicrophone = false,
             bool addTimeMarker = false);
@@ -457,12 +448,12 @@
   int RunMixingTest(int num_remote_channels, int num_local_channels,
                     int16_t input_value, int16_t max_output_value,
                     int16_t min_output_value);
-
+ private:
   VoETestManager& _mgr;
+ private:
   int _errCode;
   bool _alive;
   bool _listening[32];
-  scoped_ptr<webrtc::VoiceChannelTransport> voice_channel_transports_[32];
   bool _playing[32];
   bool _sending[32];
 };
diff --git a/voice_engine/test/auto_test/voe_stress_test.cc b/voice_engine/test/auto_test/voe_stress_test.cc
index 519bf83..c921913 100644
--- a/voice_engine/test/auto_test/voe_stress_test.cc
+++ b/voice_engine/test/auto_test/voe_stress_test.cc
@@ -23,12 +23,10 @@
 #endif
 
 #include "webrtc/voice_engine/test/auto_test/voe_stress_test.h"
+#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"
 
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
 #include "webrtc/system_wrappers/interface/sleep.h"
 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"
 #include "webrtc/voice_engine/voice_engine_defines.h"  // defines build macros
 
 using namespace webrtc;
@@ -124,7 +122,6 @@
 
   // Get sub-API pointers
   VoEBase* base = _mgr.BasePtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
 
   // Set trace
   //     VALIDATE_STRESS(base->SetTraceFileName(
@@ -150,12 +147,9 @@
   printf("Test will take approximately %d minutes. \n",
          numberOfLoops * loopSleep / 1000 / 60 + 1);
 
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(voe_network, 0));
-
   for (i = 0; i < numberOfLoops; ++i) {
-    voice_channel_transport->SetSendDestination("127.0.0.1", 4800);
-    voice_channel_transport->SetLocalReceiver(4800);
+    VALIDATE_STRESS(base->SetLocalReceiver(0, 4800));
+    VALIDATE_STRESS(base->SetSendDestination(0, 4800, "127.0.0.1"));
     VALIDATE_STRESS(base->StartReceive(0));
     VALIDATE_STRESS(base->StartPlayout(0));
     VALIDATE_STRESS(base->StartSend(0));
@@ -168,9 +162,8 @@
   }
   ANL();
 
-  VALIDATE_STRESS(voice_channel_transport->SetSendDestination("127.0.0.1",
-                                                              4800));
-  VALIDATE_STRESS(voice_channel_transport->SetLocalReceiver(4800));
+  VALIDATE_STRESS(base->SetLocalReceiver(0, 4800));
+  VALIDATE_STRESS(base->SetSendDestination(0, 4800, "127.0.0.1"));
   VALIDATE_STRESS(base->StartReceive(0));
   VALIDATE_STRESS(base->StartPlayout(0));
   VALIDATE_STRESS(base->StartSend(0));
diff --git a/voice_engine/test/auto_test/voe_unit_test.cc b/voice_engine/test/auto_test/voe_unit_test.cc
index 8c4a7fb..b152aab 100644
--- a/voice_engine/test/auto_test/voe_unit_test.cc
+++ b/voice_engine/test/auto_test/voe_unit_test.cc
@@ -248,17 +248,13 @@
                             bool send, bool fileAsMic, bool localFile) {
   VoEBase* base = _mgr.BasePtr();
   VoEFile* file = _mgr.FilePtr();
-  VoENetwork* voe_network = _mgr.NetworkPtr();
 
   _listening[channel] = false;
   _playing[channel] = false;
   _sending[channel] = false;
-  voice_channel_transports_[channel].reset(
-      new VoiceChannelTransport(voe_network, channel));
-  
-  CHECK(voice_channel_transports_[channel]->SetLocalReceiver(rtpPort));
-  CHECK(voice_channel_transports_[channel]->SetSendDestination("127.0.0.1",
-                                                               rtpPort));
+
+  CHECK(base->SetLocalReceiver(channel, rtpPort));
+  CHECK(base->SetSendDestination(channel, rtpPort, "127.0.0.1"));
   if (listen) {
     _listening[channel] = true;
     CHECK(base->StartReceive(channel));
diff --git a/voice_engine/test/auto_test/voe_unit_test.h b/voice_engine/test/auto_test/voe_unit_test.h
index 8db8d67..346713a 100644
--- a/voice_engine/test/auto_test/voe_unit_test.h
+++ b/voice_engine/test/auto_test/voe_unit_test.h
@@ -11,9 +11,7 @@
 #ifndef WEBRTC_VOICE_ENGINE_VOE_UNIT_TEST_H
 #define WEBRTC_VOICE_ENGINE_VOE_UNIT_TEST_H
 
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"
+#include "voice_engine/test/auto_test/voe_standard_test.h"
 
 namespace voetest {
 
@@ -59,7 +57,6 @@
   bool _listening[32];
   bool _playing[32];
   bool _sending[32];
-  scoped_ptr<webrtc::VoiceChannelTransport> voice_channel_transports_[32];
 
  private:
   bool _extOnOff;
diff --git a/voice_engine/test/cmd_test/voe_cmd_test.cc b/voice_engine/test/cmd_test/voe_cmd_test.cc
index d4bfc4b..2035e4e 100644
--- a/voice_engine/test/cmd_test/voe_cmd_test.cc
+++ b/voice_engine/test/cmd_test/voe_cmd_test.cc
@@ -18,6 +18,8 @@
 #include <vector>
 
 #include "gtest/gtest.h"
+#include "test/testsupport/fileutils.h"
+
 #include "voe_errors.h"
 #include "voe_base.h"
 #include "voe_codec.h"
@@ -33,15 +35,14 @@
 #include "voe_network.h"
 #include "voe_neteq_stats.h"
 #include "engine_configurations.h"
-#include "webrtc/system_wrappers/interface/scoped_ptr.h"
-#include "webrtc/test/udp_transport/include/channel_transport.h"
-#include "webrtc/test/testsupport/fileutils.h"
 
 // Enable this this flag to run this test with hard coded
 // IP/Port/codec and start test automatically with key input
 // it could be useful in repeat tests.
 //#define DEBUG
 
+// #define EXTERNAL_TRANSPORT
+
 using namespace webrtc;
 
 #define VALIDATE                                                        \
@@ -69,6 +70,29 @@
 
 void RunTest(std::string out_path);
 
+#ifdef EXTERNAL_TRANSPORT
+
+class my_transportation : public Transport
+{
+  int SendPacket(int channel,const void *data,int len);
+  int SendRTCPPacket(int channel, const void *data, int len);
+};
+
+int my_transportation::SendPacket(int channel,const void *data,int len)
+{
+  netw->ReceivedRTPPacket(channel, data, len);
+  return 0;
+}
+
+int my_transportation::SendRTCPPacket(int channel, const void *data, int len)
+{
+  netw->ReceivedRTCPPacket(channel, data, len);
+  return 0;
+}
+
+my_transportation my_transport;
+#endif
+
 class MyObserver : public VoiceEngineObserver {
  public:
    virtual void CallbackOnError(const int channel, const int err_code);
@@ -246,24 +270,44 @@
   cnt++;
 
   int j = 0;
+#ifdef EXTERNAL_TRANSPORT
+  my_transportation ch0transport;
+  printf("Enabling external transport \n");
+  netw->RegisterExternalTransport(0, ch0transport);
+#else
   char ip[64];
 #ifdef DEBUG
   strcpy(ip, "127.0.0.1");
 #else
+  char localip[64];
+  netw->GetLocalIP(localip);
+  printf("local IP:%s\n", localip);
+
   printf("1. 127.0.0.1 \n");
   printf("2. Specify IP \n");
   ASSERT_EQ(1, scanf("%i", &i));
 
-  if (1 == i) {
+  if (1 == i)
     strcpy(ip, "127.0.0.1");
-  } else {
+  else {
     printf("Specify remote IP: ");
     ASSERT_EQ(1, scanf("%s", ip));
   }
 #endif
 
-  int rPort = 8500;
-#ifndef DEBUG
+  int colons(0);
+  while (ip[j] != '\0' && j < 64 && !(colons = (ip[j++] == ':')))
+    ;
+  if (colons) {
+    printf("Enabling IPv6\n");
+    res = netw->EnableIPv6(0);
+    VALIDATE;
+  }
+
+  int rPort;
+#ifdef DEBUG
+  rPort=8500;
+#else
   printf("Specify remote port (1=1234): ");
   ASSERT_EQ(1, scanf("%i", &rPort));
   if (1 == rPort)
@@ -271,24 +315,23 @@
   printf("Set Send port \n");
 #endif
 
-  scoped_ptr<VoiceChannelTransport> voice_channel_transport(
-      new VoiceChannelTransport(netw, chan));
-
   printf("Set Send IP \n");
-  res = voice_channel_transport->SetSendDestination(ip, rPort);
+  res = base1->SetSendDestination(chan, rPort, ip);
   VALIDATE;
 
-  int lPort = 8500;
-#ifndef DEBUG
+  int lPort;
+#ifdef DEBUG
+  lPort=8500;
+#else
   printf("Specify local port (1=1234): ");
   ASSERT_EQ(1, scanf("%i", &lPort));
   if (1 == lPort)
     lPort = 1234;
   printf("Set Rec Port \n");
 #endif
-
-  res = voice_channel_transport->SetLocalReceiver(lPort);
+  res = base1->SetLocalReceiver(chan, lPort);
   VALIDATE;
+#endif
 
   printf("\n");
   for (i = 0; i < codec->NumOfCodecs(); i++) {
@@ -324,19 +367,12 @@
 #endif
   int channel_index = 0;
   std::vector<int> channels(kMaxNumChannels);
-  std::vector<scoped_ptr<VoiceChannelTransport> > voice_channel_transports;
-  
   for (i = 0; i < kMaxNumChannels; ++i) {
     channels[i] = base1->CreateChannel();
     int port = rPort + (i + 1) * 2;
-    
-    voice_channel_transports[i].reset(
-        new VoiceChannelTransport(netw, channels[i]));
-
-    printf("Set Send IP \n");
-    res = voice_channel_transports[i]->SetSendDestination(ip, port);
+    res = base1->SetSendDestination(channels[i], port, ip);
     VALIDATE;
-    res = voice_channel_transports[i]->SetLocalReceiver(port);
+    res = base1->SetLocalReceiver(channels[i], port);
     VALIDATE;
     res = codec->SetSendCodec(channels[i], cinst);
     VALIDATE;
diff --git a/voice_engine/test/voice_engine_tests.gypi b/voice_engine/test/voice_engine_tests.gypi
index af6cb93..d02ef08 100644
--- a/voice_engine/test/voice_engine_tests.gypi
+++ b/voice_engine/test/voice_engine_tests.gypi
@@ -20,7 +20,6 @@
         '<(DEPTH)/testing/gmock.gyp:gmock',
         '<(DEPTH)/third_party/google-gflags/google-gflags.gyp:google-gflags',
         '<(webrtc_root)/test/libtest/libtest.gyp:libtest',
-        '<(webrtc_root)/test/udp_transport.gyp:udp_transport',
       ],
       'include_dirs': [
         'auto_test',
@@ -60,6 +59,7 @@
         'auto_test/standard/mixing_test.cc',
         'auto_test/standard/neteq_stats_test.cc',
         'auto_test/standard/neteq_test.cc',
+        'auto_test/standard/network_before_streaming_test.cc',
         'auto_test/standard/network_test.cc',
         'auto_test/standard/rtp_rtcp_before_streaming_test.cc',
         'auto_test/standard/rtp_rtcp_test.cc',
@@ -102,7 +102,6 @@
         '<(DEPTH)/testing/gtest.gyp:gtest',
         'voice_engine_core',
         '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
-        '<(webrtc_root)/test/udp_transport.gyp:udp_transport',
       ],
       'sources': [
         'cmd_test/voe_cmd_test.cc',
diff --git a/voice_engine/voe_base_impl.cc b/voice_engine/voe_base_impl.cc
index 7446c22..864b6da 100644
--- a/voice_engine/voe_base_impl.cc
+++ b/voice_engine/voe_base_impl.cc
@@ -683,9 +683,265 @@
     {
         return -1;
     }
+
     return 0;
 }
 
+int VoEBaseImpl::SetLocalReceiver(int channel, int port, int RTCPport,
+                                  const char ipAddr[64],
+                                  const char multiCastAddr[64])
+{
+    //  Inititialize local receive sockets (RTP and RTCP).
+    //
+    //  The sockets are always first closed and then created again by this
+    //  function call. The created sockets are by default also used for
+    // transmission (unless source port is set in SetSendDestination).
+    //
+    //  Note that, sockets can also be created automatically if a user calls
+    //  SetSendDestination and StartSend without having called SetLocalReceiver
+    // first. The sockets are then created at the first packet transmission.
+
+    CriticalSectionScoped cs(_shared->crit_sec());
+    if (ipAddr == NULL && multiCastAddr == NULL)
+    {
+        WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
+            VoEId(_shared->instance_id(), -1),
+            "SetLocalReceiver(channel=%d, port=%d, RTCPport=%d)",
+            channel, port, RTCPport);
+    }
+    else if (ipAddr != NULL && multiCastAddr == NULL)
+    {
+        WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
+          VoEId(_shared->instance_id(), -1),
+          "SetLocalReceiver(channel=%d, port=%d, RTCPport=%d, ipAddr=%s)",
+          channel, port, RTCPport, ipAddr);
+    }
+    else if (ipAddr == NULL && multiCastAddr != NULL)
+    {
+        WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
+            VoEId(_shared->instance_id(), -1),
+            "SetLocalReceiver(channel=%d, port=%d, RTCPport=%d, "
+            "multiCastAddr=%s)", channel, port, RTCPport, multiCastAddr);
+    }
+    else
+    {
+        WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
+            VoEId(_shared->instance_id(), -1),
+            "SetLocalReceiver(channel=%d, port=%d, RTCPport=%d, "
+            "ipAddr=%s, multiCastAddr=%s)", channel, port, RTCPport, ipAddr,
+            multiCastAddr);
+    }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    if ((port < 0) || (port > 65535))
+    {
+        _shared->SetLastError(VE_INVALID_PORT_NMBR, kTraceError,
+            "SetLocalReceiver() invalid RTP port");
+        return -1;
+    }
+    if (((RTCPport != kVoEDefault) && (RTCPport < 0)) || ((RTCPport
+            != kVoEDefault) && (RTCPport > 65535)))
+    {
+        _shared->SetLastError(VE_INVALID_PORT_NMBR, kTraceError,
+            "SetLocalReceiver() invalid RTCP port");
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "SetLocalReceiver() failed to locate channel");
+        return -1;
+    }
+
+    // Cast RTCP port. In the RTP module 0 corresponds to RTP port + 1 in
+    // the module, which is the default.
+    WebRtc_UWord16 rtcpPortUW16(0);
+    if (RTCPport != kVoEDefault)
+    {
+        rtcpPortUW16 = static_cast<WebRtc_UWord16> (RTCPport);
+    }
+
+    return channelPtr->SetLocalReceiver(port, rtcpPortUW16, ipAddr,
+                                        multiCastAddr);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED,
+        kTraceWarning, "SetLocalReceiver() VoE is built for external "
+        "transport");
+    return -1;
+#endif
+}
+
+int VoEBaseImpl::GetLocalReceiver(int channel, int& port, int& RTCPport,
+                                  char ipAddr[64])
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "GetLocalReceiver(channel=%d, ipAddr[]=?)", channel);
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "SetLocalReceiver() failed to locate channel");
+        return -1;
+    }
+    WebRtc_Word32 ret = channelPtr->GetLocalReceiver(port, RTCPport, ipAddr);
+    if (ipAddr != NULL)
+    {
+        WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
+            VoEId(_shared->instance_id(), -1),
+            "GetLocalReceiver() => port=%d, RTCPport=%d, ipAddr=%s",
+            port, RTCPport, ipAddr);
+    }
+    else
+    {
+        WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
+          VoEId(_shared->instance_id(), -1),
+          "GetLocalReceiver() => port=%d, RTCPport=%d", port, RTCPport);
+    }
+    return ret;
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "SetLocalReceiver() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+int VoEBaseImpl::SetSendDestination(int channel, int port, const char* ipaddr,
+                                    int sourcePort, int RTCPport)
+{
+    WEBRTC_TRACE(
+                 kTraceApiCall,
+                 kTraceVoice,
+                 VoEId(_shared->instance_id(), -1),
+                 "SetSendDestination(channel=%d, port=%d, ipaddr=%s,"
+                 "sourcePort=%d, RTCPport=%d)",
+                 channel, port, ipaddr, sourcePort, RTCPport);
+    CriticalSectionScoped cs(_shared->crit_sec());
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "SetSendDestination() failed to locate channel");
+        return -1;
+    }
+    if ((port < 0) || (port > 65535))
+    {
+        _shared->SetLastError(VE_INVALID_PORT_NMBR, kTraceError,
+            "SetSendDestination() invalid RTP port");
+        return -1;
+    }
+    if (((RTCPport != kVoEDefault) && (RTCPport < 0)) || ((RTCPport
+            != kVoEDefault) && (RTCPport > 65535)))
+    {
+        _shared->SetLastError(VE_INVALID_PORT_NMBR, kTraceError,
+            "SetSendDestination() invalid RTCP port");
+        return -1;
+    }
+    if (((sourcePort != kVoEDefault) && (sourcePort < 0)) || ((sourcePort
+            != kVoEDefault) && (sourcePort > 65535)))
+    {
+        _shared->SetLastError(VE_INVALID_PORT_NMBR, kTraceError,
+            "SetSendDestination() invalid source port");
+        return -1;
+    }
+
+    // Cast RTCP port. In the RTP module 0 corresponds to RTP port + 1 in the
+    // module, which is the default.
+    WebRtc_UWord16 rtcpPortUW16(0);
+    if (RTCPport != kVoEDefault)
+    {
+        rtcpPortUW16 = static_cast<WebRtc_UWord16> (RTCPport);
+        WEBRTC_TRACE(
+                     kTraceInfo,
+                     kTraceVoice,
+                     VoEId(_shared->instance_id(), channel),
+                     "SetSendDestination() non default RTCP port %u will be "
+                     "utilized",
+                     rtcpPortUW16);
+    }
+
+    return channelPtr->SetSendDestination(port, ipaddr, sourcePort,
+                                          rtcpPortUW16);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "SetSendDestination() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+int VoEBaseImpl::GetSendDestination(int channel, int& port, char ipAddr[64],
+                                    int& sourcePort, int& RTCPport)
+{
+    WEBRTC_TRACE(
+                 kTraceApiCall,
+                 kTraceVoice,
+                 VoEId(_shared->instance_id(), -1),
+                 "GetSendDestination(channel=%d, ipAddr[]=?, sourcePort=?,"
+                 "RTCPport=?)",
+                 channel);
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "GetSendDestination() failed to locate channel");
+        return -1;
+    }
+    WebRtc_Word32 ret = channelPtr->GetSendDestination(port, ipAddr,
+                                                       sourcePort, RTCPport);
+    if (ipAddr != NULL)
+    {
+        WEBRTC_TRACE(
+                     kTraceStateInfo,
+                     kTraceVoice,
+                     VoEId(_shared->instance_id(), -1),
+                     "GetSendDestination() => port=%d, RTCPport=%d, ipAddr=%s, "
+                     "sourcePort=%d, RTCPport=%d",
+                     port, RTCPport, ipAddr, sourcePort, RTCPport);
+    }
+    else
+    {
+        WEBRTC_TRACE(
+                     kTraceStateInfo,
+                     kTraceVoice,
+                     VoEId(_shared->instance_id(), -1),
+                     "GetSendDestination() => port=%d, RTCPport=%d, "
+                     "sourcePort=%d, RTCPport=%d",
+                     port, RTCPport, sourcePort, RTCPport);
+    }
+    return ret;
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "GetSendDestination() VoE is built for external transport");
+    return -1;
+#endif
+}
+
 int VoEBaseImpl::StartReceive(int channel)
 {
     WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
@@ -808,6 +1064,15 @@
     {
         return 0;
     }
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!channelPtr->ExternalTransport()
+            && !channelPtr->SendSocketsInitialized())
+    {
+        _shared->SetLastError(VE_DESTINATION_NOT_INITED, kTraceError,
+            "StartSend() must set send destination first");
+        return -1;
+    }
+#endif
     if (StartSend() != 0)
     {
         _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceError,
@@ -880,6 +1145,16 @@
     accLen += len;
     assert(accLen < kVoiceEngineVersionMaxMessageSize);
 
+#ifdef WEBRTC_EXTERNAL_TRANSPORT
+    len = AddExternalTransportBuild(versionPtr);
+    if (len == -1)
+    {
+         return -1;
+    }
+    versionPtr += len;
+    accLen += len;
+    assert(accLen < kVoiceEngineVersionMaxMessageSize);
+#endif
 #ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
     len = AddExternalRecAndPlayoutBuild(versionPtr);
     if (len == -1)
@@ -932,6 +1207,13 @@
     return sprintf(str, "VoiceEngine 4.1.0\n");
 }
 
+#ifdef WEBRTC_EXTERNAL_TRANSPORT
+WebRtc_Word32 VoEBaseImpl::AddExternalTransportBuild(char* str) const
+{
+    return sprintf(str, "External transport build\n");
+}
+#endif
+
 #ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
 WebRtc_Word32 VoEBaseImpl::AddExternalRecAndPlayoutBuild(char* str) const
 {
diff --git a/voice_engine/voe_base_impl.h b/voice_engine/voe_base_impl.h
index 92f1539..17c6ed3 100644
--- a/voice_engine/voe_base_impl.h
+++ b/voice_engine/voe_base_impl.h
@@ -44,6 +44,25 @@
 
     virtual int DeleteChannel(int channel);
 
+    virtual int SetLocalReceiver(int channel, int port,
+                                 int RTCPport = kVoEDefault,
+                                 const char ipAddr[64] = NULL,
+                                 const char multiCastAddr[64] = NULL);
+
+    virtual int GetLocalReceiver(int channel, int& port, int& RTCPport,
+                                 char ipAddr[64]);
+
+    virtual int SetSendDestination(int channel, int port,
+                                   const char ipAddr[64],
+                                   int sourcePort = kVoEDefault,
+                                   int RTCPport = kVoEDefault);
+
+    virtual int GetSendDestination(int channel,
+                                   int& port,
+                                   char ipAddr[64],
+                                   int& sourcePort,
+                                   int& RTCPport);
+
     virtual int StartReceive(int channel);
 
     virtual int StartPlayout(int channel);
@@ -106,6 +125,9 @@
 
     WebRtc_Word32 AddBuildInfo(char* str) const;
     WebRtc_Word32 AddVoEVersion(char* str) const;
+#ifdef WEBRTC_EXTERNAL_TRANSPORT
+    WebRtc_Word32 AddExternalTransportBuild(char* str) const;
+#endif
 #ifdef WEBRTC_VOE_EXTERNAL_REC_AND_PLAYOUT
     WebRtc_Word32 AddExternalRecAndPlayoutBuild(char* str) const;
 #endif
@@ -117,6 +139,7 @@
     WebRtc_UWord32 _oldMicLevel;
     AudioFrame _audioFrame;
     voe::SharedData* _shared;
+
 };
 
 } // namespace webrtc
diff --git a/voice_engine/voe_network_impl.cc b/voice_engine/voe_network_impl.cc
index 6c4cfc2..c563900 100644
--- a/voice_engine/voe_network_impl.cc
+++ b/voice_engine/voe_network_impl.cc
@@ -170,6 +170,504 @@
     return channelPtr->ReceivedRTCPPacket((const WebRtc_Word8*) data, length);
 }
 
+int VoENetworkImpl::GetSourceInfo(int channel,
+                                  int& rtpPort,
+                                  int& rtcpPort,
+                                  char ipAddr[64])
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "GetSourceInfo(channel=%d, rtpPort=?, rtcpPort=?, ipAddr[]=?)",
+                 channel);
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    if (NULL == ipAddr)
+    {
+        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
+            "GetSourceInfo() invalid IP-address buffer");
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "GetSourceInfo() failed to locate channel");
+        return -1;
+    }
+    if (channelPtr->ExternalTransport())
+    {
+        _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "GetSourceInfo() external transport is enabled");
+        return -1;
+    }
+    return channelPtr->GetSourceInfo(rtpPort, rtcpPort, ipAddr);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "GetSourceInfo() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+int VoENetworkImpl::GetLocalIP(char ipAddr[64], bool ipv6)
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "GetLocalIP(ipAddr[]=?, ipv6=%d)", ipv6);
+    IPHONE_NOT_SUPPORTED(_shared->statistics());
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    if (NULL == ipAddr)
+    {
+        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
+            "GetLocalIP() invalid IP-address buffer");
+        return -1;
+    }
+
+    // Create a temporary socket module to ensure that this method can be
+    // called also when no channels are created.
+    WebRtc_UWord8 numSockThreads(1);
+    UdpTransport* socketPtr =
+        UdpTransport::Create(
+            -1,
+            numSockThreads);
+    if (NULL == socketPtr)
+    {
+        _shared->SetLastError(VE_SOCKET_TRANSPORT_MODULE_ERROR, kTraceError,
+            "GetLocalIP() failed to create socket module");
+        return -1;
+    }
+
+    // Use a buffer big enough for IPv6 addresses and initialize it with zeros.
+    char localIPAddr[256] = {0};
+
+    if (ipv6)
+    {
+        char localIP[16];
+        if (socketPtr->LocalHostAddressIPV6(localIP) != 0)
+        {
+            _shared->SetLastError(VE_INVALID_IP_ADDRESS, kTraceError,
+                "GetLocalIP() failed to retrieve local IP - 1");
+            UdpTransport::Destroy(socketPtr);
+            return -1;
+        }
+        // Convert 128-bit address to character string (a:b:c:d:e:f:g:h)
+        sprintf(localIPAddr,
+                "%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x%.2x:%.2x"
+                "%.2x:%.2x%.2x",
+                localIP[0], localIP[1], localIP[2], localIP[3], localIP[4],
+                localIP[5], localIP[6], localIP[7], localIP[8], localIP[9],
+                localIP[10], localIP[11], localIP[12], localIP[13],
+                localIP[14], localIP[15]);
+    }
+    else
+    {
+        WebRtc_UWord32 localIP(0);
+        // Read local IP (as 32-bit address) from the socket module
+        if (socketPtr->LocalHostAddress(localIP) != 0)
+        {
+            _shared->SetLastError(VE_INVALID_IP_ADDRESS, kTraceError,
+                "GetLocalIP() failed to retrieve local IP - 2");
+            UdpTransport::Destroy(socketPtr);
+            return -1;
+        }
+        // Convert 32-bit address to character string (x.y.z.w)
+        sprintf(localIPAddr, "%d.%d.%d.%d", (int) ((localIP >> 24) & 0x0ff),
+                (int) ((localIP >> 16) & 0x0ff),
+                (int) ((localIP >> 8) & 0x0ff),
+                (int) (localIP & 0x0ff));
+    }
+
+    strcpy(ipAddr, localIPAddr);
+
+    UdpTransport::Destroy(socketPtr);
+
+    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
+        VoEId(_shared->instance_id(), -1),
+        "GetLocalIP() => ipAddr=%s", ipAddr);
+    return 0;
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "GetLocalIP() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+int VoENetworkImpl::EnableIPv6(int channel)
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "EnableIPv6(channel=%d)", channel);
+    ANDROID_NOT_SUPPORTED(_shared->statistics());
+    IPHONE_NOT_SUPPORTED(_shared->statistics());
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "EnableIPv6() failed to locate channel");
+        return -1;
+    }
+    if (channelPtr->ExternalTransport())
+    {
+        _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "EnableIPv6() external transport is enabled");
+        return -1;
+    }
+    return channelPtr->EnableIPv6();
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "EnableIPv6() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+bool VoENetworkImpl::IPv6IsEnabled(int channel)
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+               "IPv6IsEnabled(channel=%d)", channel);
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return false;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "IPv6IsEnabled() failed to locate channel");
+        return false;
+    }
+    if (channelPtr->ExternalTransport())
+    {
+        _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "IPv6IsEnabled() external transport is enabled");
+        return false;
+    }
+    return channelPtr->IPv6IsEnabled();
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "IPv6IsEnabled() VoE is built for external transport");
+    return false;
+#endif
+}
+
+int VoENetworkImpl::SetSourceFilter(int channel,
+                                    int rtpPort,
+                                    int rtcpPort,
+                                    const char ipAddr[64])
+{
+    (ipAddr == NULL) ? WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
+                                    VoEId(_shared->instance_id(), -1),
+                                    "SetSourceFilter(channel=%d, rtpPort=%d,"
+                                    " rtcpPort=%d)",
+                                    channel, rtpPort, rtcpPort)
+                     : WEBRTC_TRACE(kTraceApiCall, kTraceVoice,
+                                    VoEId(_shared->instance_id(), -1),
+                                    "SetSourceFilter(channel=%d, rtpPort=%d,"
+                                    " rtcpPort=%d, ipAddr=%s)",
+                                    channel, rtpPort, rtcpPort, ipAddr);
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    if ((rtpPort < 0) || (rtpPort > 65535))
+    {
+        _shared->SetLastError(VE_INVALID_PORT_NMBR, kTraceError,
+            "SetSourceFilter() invalid RTP port");
+        return -1;
+    }
+    if ((rtcpPort < 0) || (rtcpPort > 65535))
+    {
+        _shared->SetLastError(VE_INVALID_PORT_NMBR, kTraceError,
+            "SetSourceFilter() invalid RTCP port");
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "SetSourceFilter() failed to locate channel");
+        return -1;
+    }
+    if (channelPtr->ExternalTransport())
+    {
+        _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "SetSourceFilter() external transport is enabled");
+        return -1;
+    }
+    return channelPtr->SetSourceFilter(rtpPort, rtcpPort, ipAddr);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "SetSourceFilter() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+int VoENetworkImpl::GetSourceFilter(int channel,
+                                    int& rtpPort,
+                                    int& rtcpPort,
+                                    char ipAddr[64])
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "GetSourceFilter(channel=%d, rtpPort=?, rtcpPort=?, "
+                 "ipAddr[]=?)",
+                 channel);
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    if (NULL == ipAddr)
+    {
+        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
+            "GetSourceFilter() invalid IP-address buffer");
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "GetSourceFilter() failed to locate channel");
+        return -1;
+    }
+    if (channelPtr->ExternalTransport())
+    {
+        _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "GetSourceFilter() external transport is enabled");
+        return -1;
+    }
+    return channelPtr->GetSourceFilter(rtpPort, rtcpPort, ipAddr);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "GetSourceFilter() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+int VoENetworkImpl::SetSendTOS(int channel,
+                               int DSCP,
+                               int priority,
+                               bool useSetSockopt)
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "SetSendTOS(channel=%d, DSCP=%d, useSetSockopt=%d)",
+                 channel, DSCP, useSetSockopt);
+
+#if !defined(_WIN32) && !defined(WEBRTC_LINUX) && !defined(WEBRTC_MAC)
+    _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceWarning,
+        "SetSendTOS() is not supported on this platform");
+    return -1;
+#endif
+
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    if ((DSCP < 0) || (DSCP > 63))
+    {
+        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
+            "SetSendTOS() Invalid DSCP value");
+        return -1;
+    }
+#if defined(_WIN32) || defined(WEBRTC_LINUX)
+    if ((priority < -1) || (priority > 7))
+    {
+        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
+            "SetSendTOS() Invalid priority value");
+        return -1;
+    }
+#else
+    if (-1 != priority)
+    {
+        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
+            "SetSendTOS() priority not supported");
+        return -1;
+    }
+#endif
+#if defined(_WIN32)
+    if ((priority >= 0) && useSetSockopt)
+    {
+        // On Windows, priority and useSetSockopt cannot be combined
+        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
+            "SetSendTOS() priority and useSetSockopt conflict");
+        return -1;
+    }
+#endif
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "SetSendTOS() failed to locate channel");
+        return -1;
+    }
+    if (channelPtr->ExternalTransport())
+    {
+        _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "SetSendTOS() external transport is enabled");
+        return -1;
+    }
+#if defined(WEBRTC_LINUX) || defined(WEBRTC_MAC)
+    useSetSockopt = true;
+    WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "   force useSetSockopt=true since there is no alternative"
+                 " implementation");
+#endif
+
+    return channelPtr->SetSendTOS(DSCP, priority, useSetSockopt);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "SetSendTOS() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+int VoENetworkImpl::GetSendTOS(int channel,
+                               int& DSCP,
+                               int& priority,
+                               bool& useSetSockopt)
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "GetSendTOS(channel=%d)", channel);
+
+#if !defined(_WIN32) && !defined(WEBRTC_LINUX) && !defined(WEBRTC_MAC)
+    _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceWarning,
+        "GetSendTOS() is not supported on this platform");
+    return -1;
+#endif
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "GetSendTOS() failed to locate channel");
+        return -1;
+    }
+    if (channelPtr->ExternalTransport())
+    {
+        _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "GetSendTOS() external transport is enabled");
+        return -1;
+    }
+    return channelPtr->GetSendTOS(DSCP, priority, useSetSockopt);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "GetSendTOS() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+int VoENetworkImpl::SetSendGQoS(int channel,
+                                bool enable,
+                                int serviceType,
+                                int overrideDSCP)
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "SetSendGQOS(channel=%d, enable=%d, serviceType=%d,"
+                 " overrideDSCP=%d)",
+                 channel, (int) enable, serviceType, overrideDSCP);
+    ANDROID_NOT_SUPPORTED(_shared->statistics());
+    IPHONE_NOT_SUPPORTED(_shared->statistics());
+#if !defined(_WIN32)
+    _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceWarning,
+        "SetSendGQOS() is not supported on this platform");
+    return -1;
+#elif !defined(WEBRTC_EXTERNAL_TRANSPORT)
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "SetSendGQOS() failed to locate channel");
+        return -1;
+    }
+    if (channelPtr->ExternalTransport())
+    {
+        _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "SetSendGQOS() external transport is enabled");
+        return -1;
+    }
+    return channelPtr->SetSendGQoS(enable, serviceType, overrideDSCP);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "SetSendGQOS() VoE is built for external transport");
+    return -1;
+#endif
+}
+
+int VoENetworkImpl::GetSendGQoS(int channel,
+                                bool& enabled,
+                                int& serviceType,
+                                int& overrideDSCP)
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "GetSendGQOS(channel=%d)", channel);
+    ANDROID_NOT_SUPPORTED(_shared->statistics());
+    IPHONE_NOT_SUPPORTED(_shared->statistics());
+#if !defined(_WIN32)
+    _shared->SetLastError(VE_FUNC_NOT_SUPPORTED, kTraceWarning,
+        "GetSendGQOS() is not supported on this platform");
+    return -1;
+#elif !defined(WEBRTC_EXTERNAL_TRANSPORT)
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "GetSendGQOS() failed to locate channel");
+        return -1;
+    }
+    if (channelPtr->ExternalTransport())
+    {
+        _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceError,
+            "GetSendGQOS() external transport is enabled");
+        return -1;
+    }
+    return channelPtr->GetSendGQoS(enabled, serviceType, overrideDSCP);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "GetSendGQOS() VoE is built for external transport");
+    return -1;
+#endif
+}
+
 int VoENetworkImpl::SetPacketTimeoutNotification(int channel,
                                                  bool enable,
                                                  int timeoutSeconds)
@@ -323,6 +821,52 @@
                                                     sampleTimeSeconds);
 }
 
+int VoENetworkImpl::SendUDPPacket(int channel,
+                                  const void* data,
+                                  unsigned int length,
+                                  int& transmittedBytes,
+                                  bool useRtcpSocket)
+{
+    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
+                 "SendUDPPacket(channel=%d, data=0x%x, length=%u, useRTCP=%d)",
+                 channel, data, length, useRtcpSocket);
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+    if (!_shared->statistics().Initialized())
+    {
+        _shared->SetLastError(VE_NOT_INITED, kTraceError);
+        return -1;
+    }
+    if (NULL == data)
+    {
+        _shared->SetLastError(VE_INVALID_ARGUMENT, kTraceError,
+            "SendUDPPacket() invalid data buffer");
+        return -1;
+    }
+    if (0 == length)
+    {
+        _shared->SetLastError(VE_INVALID_PACKET, kTraceError,
+            "SendUDPPacket() invalid packet size");
+        return -1;
+    }
+    voe::ScopedChannel sc(_shared->channel_manager(), channel);
+    voe::Channel* channelPtr = sc.ChannelPtr();
+    if (channelPtr == NULL)
+    {
+        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
+            "SendUDPPacket() failed to locate channel");
+        return -1;
+    }
+    return channelPtr->SendUDPPacket(data,
+                                     length,
+                                     transmittedBytes,
+                                     useRtcpSocket);
+#else
+    _shared->SetLastError(VE_EXTERNAL_TRANSPORT_ENABLED, kTraceWarning,
+        "SendUDPPacket() VoE is built for external transport");
+    return -1;
+#endif
+}
+
 #endif  // WEBRTC_VOICE_ENGINE_NETWORK_API
 
 } // namespace webrtc
diff --git a/voice_engine/voe_network_impl.h b/voice_engine/voe_network_impl.h
index 4dbe4f3..b159c81 100644
--- a/voice_engine/voe_network_impl.h
+++ b/voice_engine/voe_network_impl.h
@@ -34,6 +34,47 @@
                                    const void* data,
                                    unsigned int length);
 
+    virtual int GetSourceInfo(int channel,
+                              int& rtpPort,
+                              int& rtcpPort,
+                              char ipAddr[64]);
+
+    virtual int GetLocalIP(char ipAddr[64], bool ipv6 = false);
+
+    virtual int EnableIPv6(int channel);
+
+    virtual bool IPv6IsEnabled(int channel);
+
+    virtual int SetSourceFilter(int channel,
+                                int rtpPort,
+                                int rtcpPort,
+                                const char ipAddr[64] = 0);
+
+    virtual int GetSourceFilter(int channel,
+                                int& rtpPort,
+                                int& rtcpPort,
+                                char ipAddr[64]);
+
+    virtual int SetSendTOS(int channel,
+                           int DSCP,
+                           int priority = -1,
+                           bool useSetSockopt = false);
+
+    virtual int GetSendTOS(int channel,
+                           int& DSCP,
+                           int& priority,
+                           bool& useSetSockopt);
+
+    virtual int SetSendGQoS(int channel,
+                            bool enable,
+                            int serviceType,
+                            int overrideDSCP);
+
+    virtual int GetSendGQoS(int channel,
+                            bool& enabled,
+                            int& serviceType,
+                            int& overrideDSCP);
+
     virtual int SetPacketTimeoutNotification(int channel,
                                              bool enable,
                                              int timeoutSeconds = 2);
@@ -55,6 +96,12 @@
                                              bool& enabled,
                                              int& sampleTimeSeconds);
 
+    virtual int SendUDPPacket(int channel,
+                              const void* data,
+                              unsigned int length,
+                              int& transmittedBytes,
+                              bool useRtcpSocket = false);
+
 protected:
     VoENetworkImpl(voe::SharedData* shared);
     virtual ~VoENetworkImpl();
diff --git a/voice_engine/voice_engine_core.gypi b/voice_engine/voice_engine_core.gypi
index 21bfca4..1c28c0d 100644
--- a/voice_engine/voice_engine_core.gypi
+++ b/voice_engine/voice_engine_core.gypi
@@ -20,6 +20,7 @@
         '<(webrtc_root)/modules/modules.gyp:audio_processing',
         '<(webrtc_root)/modules/modules.gyp:media_file',
         '<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
+        '<(webrtc_root)/modules/modules.gyp:udp_transport',
         '<(webrtc_root)/modules/modules.gyp:webrtc_utility',
         '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
       ],
@@ -133,6 +134,7 @@
             '<(webrtc_root)/modules/modules.gyp:audio_conference_mixer',
             '<(webrtc_root)/modules/modules.gyp:media_file',
             '<(webrtc_root)/modules/modules.gyp:rtp_rtcp',
+            '<(webrtc_root)/modules/modules.gyp:udp_transport',
             '<(webrtc_root)/modules/modules.gyp:webrtc_utility',
             '<(webrtc_root)/system_wrappers/source/system_wrappers.gyp:system_wrappers',
           ],