summaryrefslogtreecommitdiff
path: root/voice_engine
diff options
context:
space:
mode:
authorpwestin@webrtc.org <pwestin@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2013-03-13 23:20:57 +0000
committerpwestin@webrtc.org <pwestin@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d>2013-03-13 23:20:57 +0000
commit912b7f727086279bfa950dce96953fe018f49580 (patch)
tree4afcdf076abaae606bf7f4c500b8ad76e90301e0 /voice_engine
parent40749c1740c81cf0e637f4d3434c5d24619b0580 (diff)
downloadwebrtc-912b7f727086279bfa950dce96953fe018f49580.tar.gz
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
Diffstat (limited to 'voice_engine')
-rw-r--r--voice_engine/channel.cc1042
-rw-r--r--voice_engine/channel.h35
-rw-r--r--voice_engine/include/voe_base.h23
-rw-r--r--voice_engine/include/voe_network.h52
-rw-r--r--voice_engine/test/auto_test/fixtures/after_initialization_fixture.h21
-rw-r--r--voice_engine/test/auto_test/fixtures/after_streaming_fixture.cc8
-rw-r--r--voice_engine/test/auto_test/fixtures/after_streaming_fixture.h2
-rw-r--r--voice_engine/test/auto_test/standard/mixing_test.cc13
-rw-r--r--voice_engine/test/auto_test/standard/network_before_streaming_test.cc55
-rw-r--r--voice_engine/test/auto_test/standard/network_test.cc73
-rw-r--r--voice_engine/test/auto_test/standard/rtp_rtcp_test.cc11
-rw-r--r--voice_engine/test/auto_test/voe_cpu_test.cc15
-rw-r--r--voice_engine/test/auto_test/voe_extended_test.cc1999
-rw-r--r--voice_engine/test/auto_test/voe_extended_test.h19
-rw-r--r--voice_engine/test/auto_test/voe_stress_test.cc17
-rw-r--r--voice_engine/test/auto_test/voe_unit_test.cc10
-rw-r--r--voice_engine/test/auto_test/voe_unit_test.h5
-rw-r--r--voice_engine/test/cmd_test/voe_cmd_test.cc84
-rw-r--r--voice_engine/test/voice_engine_tests.gypi3
-rw-r--r--voice_engine/voe_base_impl.cc282
-rw-r--r--voice_engine/voe_base_impl.h23
-rw-r--r--voice_engine/voe_network_impl.cc544
-rw-r--r--voice_engine/voe_network_impl.h47
-rw-r--r--voice_engine/voice_engine_core.gypi2
24 files changed, 4029 insertions, 356 deletions
diff --git a/voice_engine/channel.cc b/voice_engine/channel.cc
index 7691bf09..1eabee84 100644
--- a/voice_engine/channel.cc
+++ b/voice_engine/channel.cc
@@ -332,6 +332,163 @@ Channel::SendRTCPPacket(int channel, const void *data, int len)
}
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 @@ Channel::Channel(const WebRtc_Word32 channelId,
_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 @@ Channel::~Channel()
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 @@ Channel::~Channel()
" (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 @@ Channel::~Channel()
}
// Destroy modules
+#ifndef WEBRTC_EXTERNAL_TRANSPORT
+ UdpTransport::Destroy(
+ &_socketTransportModule);
+#endif
AudioCodingModule::Destroy(&_audioCodingModule);
#ifdef WEBRTC_SRTP
SrtpModule::DestroySrtpModule(&_srtpModule);
@@ -1097,7 +1284,12 @@ Channel::Init()
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 @@ Channel::Init()
}
#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 @@ Channel::StartReceiving()
// 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 @@ Channel::StopReceiving()
{
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 @@ Channel::StopReceiving()
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 @@ WebRtc_Word32 Channel::RegisterExternalTransport(Transport& transport)
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,82 +2675,397 @@ Channel::DeRegisterExternalTransport()
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()");
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
+ "Channel::ReceivedRTPPacket()");
+ const char dummyIP[] = "127.0.0.1";
+ IncomingRTPPacket(data, length, dummyIP, 0);
+ return 0;
+}
- // 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");
- }
+WebRtc_Word32
+Channel::ReceivedRTCPPacket(const WebRtc_Word8* data, WebRtc_Word32 length)
+{
+ WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
+ "Channel::ReceivedRTCPPacket()");
+ const char dummyIP[] = "127.0.0.1";
+ IncomingRTCPPacket(data, length, dummyIP, 0);
+ return 0;
+}
- // 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;
+#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::ReceivedRTCPPacket(const WebRtc_Word8* data, WebRtc_Word32 length)
+Channel::EnableIPv6()
{
- WEBRTC_TRACE(kTraceStream, kTraceVoice, VoEId(_instanceId,_channelId),
- "Channel::ReceivedRTCPPacket()");
+ 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;
+}
- // 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;
- }
+bool
+Channel::IPv6IsEnabled() const
+{
+ bool isEnabled = _socketTransportModule.IpV6Enabled();
+ WEBRTC_TRACE(kTraceStateInfo, kTraceVoice, VoEId(_instanceId,_channelId),
+ "IPv6IsEnabled() => %d", isEnabled);
+ return isEnabled;
+}
- // 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");
- }
+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;
+}
- // 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_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)
{
WEBRTC_TRACE(kTraceInfo, kTraceVoice, VoEId(_instanceId,_channelId),
@@ -2327,6 +3200,65 @@ Channel::GetPeriodicDeadOrAliveStatus(bool& enabled, int& sampleTimeSeconds)
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 cdb0790e..f1c5809b 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 @@ class Channel:
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 @@ public:
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 @@ public:
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 @@ public:
{
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:
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 70cbab19..84cd4fc4 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 @@ public:
// 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 9a2ff732..10acf1c5 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 @@ public:
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 @@ public:
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 c5f05007..bbdd64d0 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 353888a6..d1e6039e 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 @@ AfterStreamingFixture::~AfterStreamingFixture() {
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::ResumePlaying() {
}
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 26e37a7b..6b0a61f3 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 @@ class AfterStreamingFixture : public AfterInitializationFixture {
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 1d2aea38..6a90c07e 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 @@ class MixingTest : public AfterInitializationFixture {
: 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 @@ class MixingTest : public AfterInitializationFixture {
// 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 @@ class MixingTest : public AfterInitializationFixture {
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 00000000..7a41e806
--- /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 f4713dc1..8bf2d11c 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 @@ class NetworkTest : public AfterStreamingFixture {
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 7815288d..3549cb36 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 @@ class RtpRtcpTest : public AfterStreamingFixture {
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 @@ class RtpRtcpTest : public AfterStreamingFixture {
}
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 2737ee82..14e4a00e 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 @@ int VoECpuTest::DoTest() {
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 @@ int VoECpuTest::DoTest() {
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 @@ int VoECpuTest::DoTest() {
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 ce269923..d4c49c44 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 @@ int ExtendedTestTransport::SendRTCPPacket(int channel, const void *data, int len
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 @@ void VoEExtendedTest::StartMedia(int channel, int rtpPort, bool listen,
_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 @@ void VoEExtendedTest::StopMedia(int channel) {
_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 @@ int VoEExtendedTest::TestBase() {
// 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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
#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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
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 @@ int VoEExtendedTest::TestBase() {
voe_base_->DeleteChannel(0);
TEST_MUSTPASS(voe_base_->Terminate());
+
return 0;
}
@@ -1071,7 +1491,7 @@ int VoEExtendedTest::TestCallReport() {
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 @@ int VoEExtendedTest::TestCallReport() {
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 @@ int VoEExtendedTest::TestCallReport() {
// 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 @@ int VoEExtendedTest::TestCodec() {
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 @@ int VoEExtendedTest::TestCodec() {
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 @@ int VoEExtendedTest::TestCodec() {
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 @@ int VoEExtendedTest::TestCodec() {
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 @@ int VoEExtendedTest::TestCodec() {
// 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 @@ int VoEExtendedTest::TestCodec() {
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 @@ int VoEExtendedTest::TestDtmf() {
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 @@ int VoEExtendedTest::TestDtmf() {
//#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 @@ int VoEExtendedTest::TestEncryption() {
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 @@ int VoEExtendedTest::TestEncryption() {
#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 @@ int VoEExtendedTest::TestExternalMedia() {
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 @@ int VoEExtendedTest::TestExternalMedia() {
#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 @@ int VoEExtendedTest::TestFile() {
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 @@ int VoEExtendedTest::TestFile() {
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 @@ int VoEExtendedTest::TestFile() {
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::TestNetEqStats() {
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 @@ int VoEExtendedTest::TestNetwork() {
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 @@ int VoEExtendedTest::TestNetwork() {
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 @@ int VoEExtendedTest::TestNetwork() {
// ------------------------------------------------------------------------
// ------------------------------------------------------------------------
+ // >> 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 @@ int VoEExtendedTest::TestNetwork() {
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 @@ int VoEExtendedTest::TestNetwork() {
// - 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 @@ int VoEExtendedTest::TestNetwork() {
// 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 @@ int VoEExtendedTest::TestNetwork() {
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 @@ int VoEExtendedTest::TestNetwork() {
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 @@ int VoEExtendedTest::TestNetwork() {
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 @@ class RTPAudioTransport: public Transport {
assert(vad == 0 || vad == 1);
assert(level >= 0 && level <= 127);
}
+
return 0;
}
@@ -4914,7 +6521,7 @@ class RTPAudioTransport: public Transport {
return 0;
}
- private:
+private:
bool mute_;
};
@@ -4951,13 +6558,8 @@ int VoEExtendedTest::TestRTP_RTCP() {
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 @@ int VoEExtendedTest::TestRTP_RTCP() {
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 @@ int VoEExtendedTest::TestRTP_RTCP() {
ANL();
// ------------------------------------------------------------------------
- // >> SetLocalSSRC
+ // >> InsertExtraRTPPacket
int i(0);
@@ -5092,6 +6690,58 @@ int VoEExtendedTest::TestRTP_RTCP() {
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 @@ int VoEExtendedTest::TestRTP_RTCP() {
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 @@ int VoEExtendedTest::TestRTP_RTCP() {
// 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 @@ int VoEExtendedTest::TestVideoSync()
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 @@ int VoEExtendedTest::TestVideoSync()
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 @@ int VoEExtendedTest::TestVolumeControl()
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 @@ int VoEExtendedTest::TestVolumeControl()
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 af549f81..c685d885 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 @@ class VoEExtendedTest : public VoiceEngineObserver,
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 @@ class VoEExtendedTest : public VoiceEngineObserver,
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 519bf838..c9219131 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 @@ int VoEStressTest::StartStopTest() {
// Get sub-API pointers
VoEBase* base = _mgr.BasePtr();
- VoENetwork* voe_network = _mgr.NetworkPtr();
// Set trace
// VALIDATE_STRESS(base->SetTraceFileName(
@@ -150,12 +147,9 @@ int VoEStressTest::StartStopTest() {
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 @@ int VoEStressTest::StartStopTest() {
}
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 8c4a7fbf..b152aabf 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 @@ int VoEUnitTest::StartMedia(int channel, int rtpPort, bool listen, bool playout,
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 8db8d676..346713a1 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 @@ class VoEUnitTest : public Encryption {
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 d4bfc4b2..2035e4ee 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 @@ VoENetEqStats* neteqst = NULL;
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 @@ void RunTest(std::string out_path) {
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 @@ void RunTest(std::string out_path) {
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 @@ void RunTest(std::string out_path) {
#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 af6cb932..d02ef08f 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 7446c224..864b6da3 100644
--- a/voice_engine/voe_base_impl.cc
+++ b/voice_engine/voe_base_impl.cc
@@ -683,9 +683,265 @@ int VoEBaseImpl::DeleteChannel(int channel)
{
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 @@ int VoEBaseImpl::StartSend(int channel)
{
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 @@ int VoEBaseImpl::GetVersion(char version[1024])
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 @@ WebRtc_Word32 VoEBaseImpl::AddVoEVersion(char* str) const
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 92f1539d..17c6ed3d 100644
--- a/voice_engine/voe_base_impl.h
+++ b/voice_engine/voe_base_impl.h
@@ -44,6 +44,25 @@ public:
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 @@ private:
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 @@ private:
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 6c4cfc2b..c5639008 100644
--- a/voice_engine/voe_network_impl.cc
+++ b/voice_engine/voe_network_impl.cc
@@ -170,6 +170,504 @@ int VoENetworkImpl::ReceivedRTCPPacket(int channel, const void* data,
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 @@ int VoENetworkImpl::GetPeriodicDeadOrAliveStatus(int channel,
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 4dbe4f32..b159c81b 100644
--- a/voice_engine/voe_network_impl.h
+++ b/voice_engine/voe_network_impl.h
@@ -34,6 +34,47 @@ public:
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 @@ public:
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 21bfca41..1c28c0d4 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',
],