Remove unused VoiceChannelTransport.

BUG=webrtc:4690

Review-Url: https://codereview.webrtc.org/2687843002
Cr-Commit-Position: refs/heads/master@{#17086}
This commit is contained in:
solenberg 2017-03-07 01:47:57 -08:00 committed by Commit bot
parent 7cb0e55823
commit 759358c9db
23 changed files with 0 additions and 8059 deletions

View File

@ -179,73 +179,8 @@ rtc_static_library("level_indicator") {
}
if (rtc_include_tests) {
config("channel_transport_warnings_config") {
if (is_win) {
cflags = [ "/wd4302" ] # cast truncation
if (is_clang) {
# GN orders flags on a target before flags from configs. The default
# config adds -Wall, and this flag have to be after -Wall -- so they need
# to come from a config and cannot be on the target directly.
cflags += [
"-Wno-parentheses-equality",
"-Wno-reorder",
"-Wno-tautological-constant-out-of-range-compare",
# See https://bugs.chromium.org/p/webrtc/issues/detail?id=6268
# for -Wno-thread-safety-analysis
"-Wno-thread-safety-analysis",
"-Wno-unused-private-field",
]
}
}
}
rtc_static_library("channel_transport") {
testonly = true
sources = [
"test/channel_transport/channel_transport.cc",
"test/channel_transport/channel_transport.h",
"test/channel_transport/traffic_control_win.cc",
"test/channel_transport/traffic_control_win.h",
"test/channel_transport/udp_socket2_manager_win.cc",
"test/channel_transport/udp_socket2_manager_win.h",
"test/channel_transport/udp_socket2_win.cc",
"test/channel_transport/udp_socket2_win.h",
"test/channel_transport/udp_socket_manager_posix.cc",
"test/channel_transport/udp_socket_manager_posix.h",
"test/channel_transport/udp_socket_manager_wrapper.cc",
"test/channel_transport/udp_socket_manager_wrapper.h",
"test/channel_transport/udp_socket_posix.cc",
"test/channel_transport/udp_socket_posix.h",
"test/channel_transport/udp_socket_wrapper.cc",
"test/channel_transport/udp_socket_wrapper.h",
"test/channel_transport/udp_transport.h",
"test/channel_transport/udp_transport_impl.cc",
"test/channel_transport/udp_transport_impl.h",
]
configs += [ ":channel_transport_warnings_config" ]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
deps = [
":voice_engine",
"..:webrtc_common",
"../api:transport_api",
"../base:rtc_base_approved",
"../system_wrappers",
"../test:test_support",
"//testing/gtest",
]
}
rtc_test("voice_engine_unittests") {
deps = [
":channel_transport",
":file_player",
":voice_engine",
"../base:rtc_base_approved",
@ -275,9 +210,6 @@ if (rtc_include_tests) {
sources = [
"channel_unittest.cc",
"file_player_unittests.cc",
"test/channel_transport/udp_socket_manager_unittest.cc",
"test/channel_transport/udp_socket_wrapper_unittest.cc",
"test/channel_transport/udp_transport_unittest.cc",
"transport_feedback_packet_loss_tracker_unittest.cc",
"utility_unittest.cc",
"voe_audio_processing_unittest.cc",
@ -313,7 +245,6 @@ if (rtc_include_tests) {
testonly = true
deps = [
":channel_transport",
":voice_engine",
"..:webrtc_common",
"../base:rtc_base_approved",

View File

@ -1,83 +0,0 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/voice_engine/test/channel_transport/channel_transport.h"
#include <stdio.h>
#if !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS)
#include "webrtc/test/gtest.h"
#endif
#include "webrtc/voice_engine/test/channel_transport/udp_transport.h"
#include "webrtc/voice_engine/include/voe_network.h"
#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
#undef NDEBUG
#include <assert.h>
#endif
namespace webrtc {
namespace test {
VoiceChannelTransport::VoiceChannelTransport(VoENetwork* voe_network,
int channel)
: channel_(channel),
voe_network_(voe_network) {
uint8_t socket_threads = 1;
socket_transport_ = UdpTransport::Create(channel, socket_threads);
int registered = voe_network_->RegisterExternalTransport(channel,
*socket_transport_);
#if !defined(WEBRTC_ANDROID) && !defined(WEBRTC_IOS)
EXPECT_EQ(0, registered);
#else
assert(registered == 0);
#endif
}
VoiceChannelTransport::~VoiceChannelTransport() {
voe_network_->DeRegisterExternalTransport(channel_);
UdpTransport::Destroy(socket_transport_);
}
void VoiceChannelTransport::IncomingRTPPacket(
const int8_t* incoming_rtp_packet,
const size_t packet_length,
const char* /*from_ip*/,
const uint16_t /*from_port*/) {
voe_network_->ReceivedRTPPacket(
channel_, incoming_rtp_packet, packet_length, PacketTime());
}
void VoiceChannelTransport::IncomingRTCPPacket(
const int8_t* incoming_rtcp_packet,
const size_t packet_length,
const char* /*from_ip*/,
const uint16_t /*from_port*/) {
voe_network_->ReceivedRTCPPacket(channel_, incoming_rtcp_packet,
packet_length);
}
int VoiceChannelTransport::SetLocalReceiver(uint16_t rtp_port) {
static const int kNumReceiveSocketBuffers = 500;
int return_value = socket_transport_->InitializeReceiveSockets(this,
rtp_port);
if (return_value == 0) {
return socket_transport_->StartReceiving(kNumReceiveSocketBuffers);
}
return return_value;
}
int VoiceChannelTransport::SetSendDestination(const char* ip_address,
uint16_t rtp_port) {
return socket_transport_->InitializeSendSockets(ip_address, rtp_port);
}
} // namespace test
} // namespace webrtc

View File

@ -1,56 +0,0 @@
/*
* Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_CHANNEL_TRANSPORT_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_CHANNEL_TRANSPORT_H_
#include "webrtc/voice_engine/test/channel_transport/udp_transport.h"
namespace webrtc {
class VoENetwork;
namespace test {
// Helper class for VoiceEngine tests.
class VoiceChannelTransport : public UdpTransportData {
public:
VoiceChannelTransport(VoENetwork* voe_network, int channel);
virtual ~VoiceChannelTransport();
// Start implementation of UdpTransportData.
void IncomingRTPPacket(const int8_t* incoming_rtp_packet,
const size_t packet_length,
const char* /*from_ip*/,
const uint16_t /*from_port*/) override;
void IncomingRTCPPacket(const int8_t* incoming_rtcp_packet,
const size_t packet_length,
const char* /*from_ip*/,
const uint16_t /*from_port*/) override;
// End implementation of UdpTransportData.
// Specifies the ports to receive RTP packets on.
int SetLocalReceiver(uint16_t rtp_port);
// Specifies the destination port and IP address for a specified channel.
int SetSendDestination(const char* ip_address, uint16_t rtp_port);
private:
int channel_;
VoENetwork* voe_network_;
UdpTransport* socket_transport_;
};
} // namespace test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_CHANNEL_TRANSPORT_H_

View File

@ -1,252 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/voice_engine/test/channel_transport/traffic_control_win.h"
#include <assert.h>
#include "webrtc/system_wrappers/include/trace.h"
namespace webrtc {
namespace test {
TrafficControlWindows* TrafficControlWindows::instance = NULL;
uint32_t TrafficControlWindows::refCounter = 0;
TrafficControlWindows::TrafficControlWindows(const int32_t id)
{
}
TrafficControlWindows* TrafficControlWindows::GetInstance(
const int32_t id)
{
if(instance != NULL)
{
WEBRTC_TRACE(
kTraceDebug,
kTraceTransport,
id,
"TrafficControlWindows - Returning already created object");
refCounter++;
return instance;
}
WEBRTC_TRACE(kTraceMemory, kTraceTransport, id,
"TrafficControlWindows - Creating new object");
instance = new TrafficControlWindows(id);
if(instance == NULL)
{
WEBRTC_TRACE(kTraceMemory, kTraceTransport, id,
"TrafficControlWindows - Error allocating memory");
return NULL;
}
instance->tcRegister = NULL;
instance->tcDeregister = NULL;
instance->tcEnumerate = NULL;
instance->tcOpenInterface = NULL;
instance->tcCloseInterface = NULL;
instance->tcAddFlow = NULL;
instance->tcDeleteFlow = NULL;
instance->tcAddFilter = NULL;
instance->tcDeleteFilter = NULL;
HMODULE trafficLib = LoadLibrary(TEXT("traffic.dll"));
if(trafficLib == NULL)
{
WEBRTC_TRACE(
kTraceWarning,
kTraceTransport,
id,
"TrafficControlWindows - No QOS support, LoadLibrary returned NULL,\
last error: %d\n",
GetLastError());
delete instance;
instance = NULL;
return NULL;
}
instance->tcRegister = (registerFn)GetProcAddress(trafficLib,
"TcRegisterClient");
instance->tcDeregister = (deregisterFn)GetProcAddress(trafficLib,
"TcDeregisterClient");
instance->tcEnumerate = (enumerateFn)GetProcAddress(
trafficLib,
"TcEnumerateInterfaces");
instance->tcOpenInterface = (openInterfaceFn)GetProcAddress(
trafficLib,
"TcOpenInterfaceW");
instance->tcCloseInterface = (closeInterfaceFn)GetProcAddress(
trafficLib,
"TcCloseInterface");
instance->tcAddFlow = (flowAddFn)GetProcAddress(trafficLib,
"TcAddFlow");
instance->tcDeleteFlow = (flowDeleteFn)GetProcAddress(trafficLib,
"TcDeleteFlow");
instance->tcAddFilter = (filterAddFn)GetProcAddress(trafficLib,
"TcAddFilter");
instance->tcDeleteFilter = (filterDeleteFn)GetProcAddress(trafficLib,
"TcDeleteFilter");
if(instance->tcRegister == NULL ||
instance->tcDeregister == NULL ||
instance->tcEnumerate == NULL ||
instance->tcOpenInterface == NULL ||
instance->tcCloseInterface == NULL ||
instance->tcAddFlow == NULL ||
instance->tcAddFilter == NULL ||
instance->tcDeleteFlow == NULL ||
instance->tcDeleteFilter == NULL)
{
delete instance;
instance = NULL;
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
id,
"TrafficControlWindows - Could not find function pointer for\
traffic control functions");
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
id,
"Tcregister : %x, tcDeregister: %x, tcEnumerate: %x,\
tcOpenInterface: %x, tcCloseInterface: %x, tcAddFlow: %x, tcAddFilter: %x,\
tcDeleteFlow: %x, tcDeleteFilter: %x",
instance->tcRegister,
instance->tcDeregister,
instance->tcEnumerate,
instance->tcOpenInterface,
instance->tcCloseInterface,
instance->tcAddFlow,
instance->tcAddFilter,
instance->tcDeleteFlow,
instance->tcDeleteFilter );
return NULL;
}
refCounter++;
return instance;
}
void TrafficControlWindows::Release(TrafficControlWindows* gtc)
{
if (0 == refCounter)
{
WEBRTC_TRACE(kTraceError, kTraceTransport, -1,
"TrafficControlWindows - Cannot release, refCounter is 0");
return;
}
if (NULL == gtc)
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, -1,
"TrafficControlWindows - Not releasing, gtc is NULL");
return;
}
WEBRTC_TRACE(kTraceDebug, kTraceTransport, -1,
"TrafficControlWindows - Releasing object");
refCounter--;
if ((0 == refCounter) && instance)
{
WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1,
"TrafficControlWindows - Deleting object");
delete instance;
instance = NULL;
}
}
ULONG TrafficControlWindows::TcRegisterClient(
ULONG TciVersion,
HANDLE ClRegCtx,
PTCI_CLIENT_FUNC_LIST ClientHandlerList,
PHANDLE pClientHandle)
{
assert(tcRegister != NULL);
return tcRegister(TciVersion, ClRegCtx, ClientHandlerList, pClientHandle);
}
ULONG TrafficControlWindows::TcDeregisterClient(HANDLE clientHandle)
{
assert(tcDeregister != NULL);
return tcDeregister(clientHandle);
}
ULONG TrafficControlWindows::TcEnumerateInterfaces(
HANDLE ClientHandle,
PULONG pBufferSize,
PTC_IFC_DESCRIPTOR interfaceBuffer)
{
assert(tcEnumerate != NULL);
return tcEnumerate(ClientHandle, pBufferSize, interfaceBuffer);
}
ULONG TrafficControlWindows::TcOpenInterfaceW(LPWSTR pInterfaceName,
HANDLE ClientHandle,
HANDLE ClIfcCtx,
PHANDLE pIfcHandle)
{
assert(tcOpenInterface != NULL);
return tcOpenInterface(pInterfaceName, ClientHandle, ClIfcCtx, pIfcHandle);
}
ULONG TrafficControlWindows::TcCloseInterface(HANDLE IfcHandle)
{
assert(tcCloseInterface != NULL);
return tcCloseInterface(IfcHandle);
}
ULONG TrafficControlWindows::TcAddFlow(HANDLE IfcHandle, HANDLE ClFlowCtx,
ULONG Flags, PTC_GEN_FLOW pGenericFlow,
PHANDLE pFlowHandle)
{
assert(tcAddFlow != NULL);
return tcAddFlow(IfcHandle, ClFlowCtx, Flags, pGenericFlow, pFlowHandle);
}
ULONG TrafficControlWindows::TcAddFilter(HANDLE FlowHandle,
PTC_GEN_FILTER pGenericFilter,
PHANDLE pFilterHandle)
{
assert(tcAddFilter != NULL);
return tcAddFilter(FlowHandle, pGenericFilter, pFilterHandle);
}
ULONG TrafficControlWindows::TcDeleteFlow(HANDLE FlowHandle)
{
assert(tcDeleteFlow != NULL);
return tcDeleteFlow(FlowHandle);
}
ULONG TrafficControlWindows::TcDeleteFilter(HANDLE FilterHandle)
{
assert(tcDeleteFilter != NULL);
return tcDeleteFilter(FilterHandle);
}
void CALLBACK MyClNotifyHandler(HANDLE ClRegCtx, HANDLE ClIfcCtx, ULONG Event,
HANDLE SubCode, ULONG BufSize, PVOID Buffer)
{
}
} // namespace test
} // namespace webrtc

View File

@ -1,99 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_TRAFFIC_CONTROL_WINDOWS_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_TRAFFIC_CONTROL_WINDOWS_H_
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
// Disable deprication warning from traffic.h
#pragma warning(disable : 4995)
#include <windows.h>
#include <qos.h>
#include <ntddndis.h>
#include <traffic.h>
#include "webrtc/system_wrappers/include/trace.h"
namespace webrtc {
namespace test {
void CALLBACK MyClNotifyHandler(HANDLE ClRegCtx, HANDLE ClIfcCtx, ULONG Event,
HANDLE SubCode, ULONG BufSize, PVOID Buffer);
typedef ULONG (WINAPI *registerFn)(ULONG, HANDLE, PTCI_CLIENT_FUNC_LIST,
PHANDLE);
typedef ULONG (WINAPI *deregisterFn)(HANDLE);
typedef ULONG (WINAPI *enumerateFn)(HANDLE, PULONG, PTC_IFC_DESCRIPTOR);
typedef ULONG (WINAPI *openInterfaceFn)(LPWSTR, HANDLE, HANDLE, PHANDLE);
typedef ULONG (WINAPI *closeInterfaceFn)(HANDLE);
typedef ULONG (WINAPI *flowAddFn)(HANDLE, HANDLE, ULONG, PTC_GEN_FLOW, PHANDLE);
typedef ULONG (WINAPI *filterAddFn)(HANDLE, PTC_GEN_FILTER, PHANDLE);
typedef ULONG (WINAPI *flowDeleteFn)(HANDLE);
typedef ULONG (WINAPI *filterDeleteFn)(HANDLE);
class TrafficControlWindows
{
public:
// Factory method. Constructor disabled.
static TrafficControlWindows* GetInstance(const int32_t id);
static void Release(TrafficControlWindows* gtc);
ULONG TcRegisterClient(ULONG TciVersion, HANDLE ClRegCtx,
PTCI_CLIENT_FUNC_LIST ClientHandlerList,
PHANDLE pClientHandle);
ULONG TcDeregisterClient(HANDLE clientHandle);
ULONG TcEnumerateInterfaces(HANDLE ClientHandle, PULONG pBufferSize,
PTC_IFC_DESCRIPTOR interfaceBuffer);
ULONG TcOpenInterfaceW(LPWSTR pInterfaceName, HANDLE ClientHandle,
HANDLE ClIfcCtx, PHANDLE pIfcHandle);
ULONG TcCloseInterface(HANDLE IfcHandle);
ULONG TcAddFlow(HANDLE IfcHandle, HANDLE ClFlowCtx, ULONG Flags,
PTC_GEN_FLOW pGenericFlow, PHANDLE pFlowHandle);
ULONG TcAddFilter(HANDLE FlowHandle, PTC_GEN_FILTER pGenericFilter,
PHANDLE pFilterHandle);
ULONG TcDeleteFlow(HANDLE FlowHandle);
ULONG TcDeleteFilter(HANDLE FilterHandle);
private:
TrafficControlWindows(const int32_t id);
TCI_CLIENT_FUNC_LIST QoSFunctions;
static TrafficControlWindows* instance;
registerFn tcRegister;
deregisterFn tcDeregister;
enumerateFn tcEnumerate;
openInterfaceFn tcOpenInterface;
closeInterfaceFn tcCloseInterface;
flowAddFn tcAddFlow;
flowDeleteFn tcDeleteFlow;
filterAddFn tcAddFilter;
filterDeleteFn tcDeleteFilter;
static uint32_t refCounter;
};
} // namespace test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_TRAFFIC_CONTROL_WINDOWS_H_

View File

@ -1,608 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h"
#include <assert.h>
#include <stdio.h>
#include "webrtc/system_wrappers/include/aligned_malloc.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket2_win.h"
namespace webrtc {
namespace test {
uint32_t UdpSocket2ManagerWindows::_numOfActiveManagers = 0;
bool UdpSocket2ManagerWindows::_wsaInit = false;
UdpSocket2ManagerWindows::UdpSocket2ManagerWindows()
: UdpSocketManager(),
_id(-1),
_stopped(false),
_init(false),
_pCrit(CriticalSectionWrapper::CreateCriticalSection()),
_ioCompletionHandle(NULL),
_numActiveSockets(0),
_event(EventWrapper::Create())
{
_managerNumber = _numOfActiveManagers++;
if(_numOfActiveManagers == 1)
{
WORD wVersionRequested = MAKEWORD(2, 2);
WSADATA wsaData;
_wsaInit = WSAStartup(wVersionRequested, &wsaData) == 0;
// TODO (hellner): seems safer to use RAII for this. E.g. what happens
// if a UdpSocket2ManagerWindows() created and destroyed
// without being initialized.
}
}
UdpSocket2ManagerWindows::~UdpSocket2ManagerWindows()
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocket2ManagerWindows(%d)::~UdpSocket2ManagerWindows()",
_managerNumber);
if(_init)
{
_pCrit->Enter();
if(_numActiveSockets)
{
_pCrit->Leave();
_event->Wait(INFINITE);
}
else
{
_pCrit->Leave();
}
StopWorkerThreads();
for (WorkerList::iterator iter = _workerThreadsList.begin();
iter != _workerThreadsList.end(); ++iter) {
delete *iter;
}
_workerThreadsList.clear();
_ioContextPool.Free();
_numOfActiveManagers--;
if(_ioCompletionHandle)
{
CloseHandle(_ioCompletionHandle);
}
if (_numOfActiveManagers == 0)
{
if(_wsaInit)
{
WSACleanup();
}
}
}
if(_pCrit)
{
delete _pCrit;
}
if(_event)
{
delete _event;
}
}
bool UdpSocket2ManagerWindows::Init(int32_t id,
uint8_t& numOfWorkThreads) {
CriticalSectionScoped cs(_pCrit);
if ((_id != -1) || (_numOfWorkThreads != 0)) {
assert(_id != -1);
assert(_numOfWorkThreads != 0);
return false;
}
_id = id;
_numOfWorkThreads = numOfWorkThreads;
return true;
}
bool UdpSocket2ManagerWindows::Start()
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocket2ManagerWindows(%d)::Start()",_managerNumber);
if(!_init)
{
StartWorkerThreads();
}
if(!_init)
{
return false;
}
_pCrit->Enter();
// Start worker threads.
_stopped = false;
int32_t error = 0;
for (WorkerList::iterator iter = _workerThreadsList.begin();
iter != _workerThreadsList.end() && !error; ++iter) {
if(!(*iter)->Start())
error = 1;
}
if(error)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::Start() error starting worker\
threads",
_managerNumber);
_pCrit->Leave();
return false;
}
_pCrit->Leave();
return true;
}
bool UdpSocket2ManagerWindows::StartWorkerThreads()
{
if(!_init)
{
_pCrit->Enter();
_ioCompletionHandle = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL,
0, 0);
if(_ioCompletionHandle == NULL)
{
int32_t error = GetLastError();
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::StartWorkerThreads()"
"_ioCompletioHandle == NULL: error:%d",
_managerNumber,error);
_pCrit->Leave();
return false;
}
// Create worker threads.
uint32_t i = 0;
bool error = false;
while(i < _numOfWorkThreads && !error)
{
UdpSocket2WorkerWindows* pWorker =
new UdpSocket2WorkerWindows(_ioCompletionHandle);
if(pWorker->Init() != 0)
{
error = true;
delete pWorker;
break;
}
_workerThreadsList.push_front(pWorker);
i++;
}
if(error)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::StartWorkerThreads() error "
"creating work threads",
_managerNumber);
// Delete worker threads.
for (WorkerList::iterator iter = _workerThreadsList.begin();
iter != _workerThreadsList.end(); ++iter) {
delete *iter;
}
_workerThreadsList.clear();
_pCrit->Leave();
return false;
}
if(_ioContextPool.Init())
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::StartWorkerThreads() error "
"initiating _ioContextPool",
_managerNumber);
_pCrit->Leave();
return false;
}
_init = true;
WEBRTC_TRACE(
kTraceDebug,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows::StartWorkerThreads %d number of work "
"threads created and initialized",
_numOfWorkThreads);
_pCrit->Leave();
}
return true;
}
bool UdpSocket2ManagerWindows::Stop()
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocket2ManagerWindows(%d)::Stop()",_managerNumber);
if(!_init)
{
return false;
}
_pCrit->Enter();
_stopped = true;
if(_numActiveSockets)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::Stop() there is still active\
sockets",
_managerNumber);
_pCrit->Leave();
return false;
}
// No active sockets. Stop all worker threads.
bool result = StopWorkerThreads();
_pCrit->Leave();
return result;
}
bool UdpSocket2ManagerWindows::StopWorkerThreads()
{
int32_t error = 0;
WEBRTC_TRACE(
kTraceDebug,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::StopWorkerThreads() Worker\
threadsStoped, numActicve Sockets=%d",
_managerNumber,
_numActiveSockets);
// Release all threads waiting for GetQueuedCompletionStatus(..).
if(_ioCompletionHandle)
{
uint32_t i = 0;
for(i = 0; i < _workerThreadsList.size(); i++)
{
PostQueuedCompletionStatus(_ioCompletionHandle, 0 ,0 , NULL);
}
}
for (WorkerList::iterator iter = _workerThreadsList.begin();
iter != _workerThreadsList.end(); ++iter) {
if((*iter)->Stop() == false)
{
error = -1;
WEBRTC_TRACE(kTraceWarning, kTraceTransport, -1,
"failed to stop worker thread");
}
}
if(error)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::StopWorkerThreads() error stopping\
worker threads",
_managerNumber);
return false;
}
return true;
}
bool UdpSocket2ManagerWindows::AddSocketPrv(UdpSocket2Windows* s)
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocket2ManagerWindows(%d)::AddSocketPrv()",_managerNumber);
if(!_init)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::AddSocketPrv() manager not\
initialized",
_managerNumber);
return false;
}
_pCrit->Enter();
if(s == NULL)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::AddSocketPrv() socket == NULL",
_managerNumber);
_pCrit->Leave();
return false;
}
if(s->GetFd() == NULL || s->GetFd() == INVALID_SOCKET)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::AddSocketPrv() socket->GetFd() ==\
%d",
_managerNumber,
(int32_t)s->GetFd());
_pCrit->Leave();
return false;
}
_ioCompletionHandle = CreateIoCompletionPort((HANDLE)s->GetFd(),
_ioCompletionHandle,
(ULONG_PTR)(s), 0);
if(_ioCompletionHandle == NULL)
{
int32_t error = GetLastError();
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::AddSocketPrv() Error adding to IO\
completion: %d",
_managerNumber,
error);
_pCrit->Leave();
return false;
}
_numActiveSockets++;
_pCrit->Leave();
return true;
}
bool UdpSocket2ManagerWindows::RemoveSocketPrv(UdpSocket2Windows* s)
{
if(!_init)
{
return false;
}
_pCrit->Enter();
_numActiveSockets--;
if(_numActiveSockets == 0)
{
_event->Set();
}
_pCrit->Leave();
return true;
}
PerIoContext* UdpSocket2ManagerWindows::PopIoContext()
{
if(!_init)
{
return NULL;
}
PerIoContext* pIoC = NULL;
if(!_stopped)
{
pIoC = _ioContextPool.PopIoContext();
}else
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocket2ManagerWindows(%d)::PopIoContext() Manager Not started",
_managerNumber);
}
return pIoC;
}
int32_t UdpSocket2ManagerWindows::PushIoContext(PerIoContext* pIoContext)
{
return _ioContextPool.PushIoContext(pIoContext);
}
IoContextPool::IoContextPool()
: _pListHead(NULL),
_init(false),
_size(0),
_inUse(0)
{
}
IoContextPool::~IoContextPool()
{
Free();
assert(_size.Value() == 0);
AlignedFree(_pListHead);
}
int32_t IoContextPool::Init(uint32_t /*increaseSize*/)
{
if(_init)
{
return 0;
}
_pListHead = (PSLIST_HEADER)AlignedMalloc(sizeof(SLIST_HEADER),
MEMORY_ALLOCATION_ALIGNMENT);
if(_pListHead == NULL)
{
return -1;
}
InitializeSListHead(_pListHead);
_init = true;
return 0;
}
PerIoContext* IoContextPool::PopIoContext()
{
if(!_init)
{
return NULL;
}
PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(_pListHead);
if(pListEntry == NULL)
{
IoContextPoolItem* item = (IoContextPoolItem*)
AlignedMalloc(
sizeof(IoContextPoolItem),
MEMORY_ALLOCATION_ALIGNMENT);
if(item == NULL)
{
return NULL;
}
memset(&item->payload.ioContext,0,sizeof(PerIoContext));
item->payload.base = item;
pListEntry = &(item->itemEntry);
++_size;
}
++_inUse;
return &((IoContextPoolItem*)pListEntry)->payload.ioContext;
}
int32_t IoContextPool::PushIoContext(PerIoContext* pIoContext)
{
// TODO (hellner): Overlapped IO should be completed at this point. Perhaps
// add an assert?
const bool overlappedIOCompleted = HasOverlappedIoCompleted(
(LPOVERLAPPED)pIoContext);
IoContextPoolItem* item = ((IoContextPoolItemPayload*)pIoContext)->base;
const int32_t usedItems = --_inUse;
const int32_t totalItems = _size.Value();
const int32_t freeItems = totalItems - usedItems;
if(freeItems < 0)
{
assert(false);
AlignedFree(item);
return -1;
}
if((freeItems >= totalItems>>1) &&
overlappedIOCompleted)
{
AlignedFree(item);
--_size;
return 0;
}
InterlockedPushEntrySList(_pListHead, &(item->itemEntry));
return 0;
}
int32_t IoContextPool::Free()
{
if(!_init)
{
return 0;
}
int32_t itemsFreed = 0;
PSLIST_ENTRY pListEntry = InterlockedPopEntrySList(_pListHead);
while(pListEntry != NULL)
{
IoContextPoolItem* item = ((IoContextPoolItem*)pListEntry);
AlignedFree(item);
--_size;
itemsFreed++;
pListEntry = InterlockedPopEntrySList(_pListHead);
}
return itemsFreed;
}
int32_t UdpSocket2WorkerWindows::_numOfWorkers = 0;
UdpSocket2WorkerWindows::UdpSocket2WorkerWindows(HANDLE ioCompletionHandle)
: _ioCompletionHandle(ioCompletionHandle),
_pThread(Run, this, "UdpSocket2ManagerWindows_thread"),
_init(false) {
_workerNumber = _numOfWorkers++;
WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1,
"UdpSocket2WorkerWindows created");
}
UdpSocket2WorkerWindows::~UdpSocket2WorkerWindows()
{
WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1,
"UdpSocket2WorkerWindows deleted");
}
bool UdpSocket2WorkerWindows::Start()
{
WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1,
"Start UdpSocket2WorkerWindows");
_pThread.Start();
_pThread.SetPriority(rtc::kRealtimePriority);
return true;
}
bool UdpSocket2WorkerWindows::Stop()
{
WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1,
"Stop UdpSocket2WorkerWindows");
_pThread.Stop();
return true;
}
int32_t UdpSocket2WorkerWindows::Init()
{
_init = true;
return 0;
}
bool UdpSocket2WorkerWindows::Run(void* obj)
{
UdpSocket2WorkerWindows* pWorker =
static_cast<UdpSocket2WorkerWindows*>(obj);
return pWorker->Process();
}
// Process should always return true. Stopping the worker threads is done in
// the UdpSocket2ManagerWindows::StopWorkerThreads() function.
bool UdpSocket2WorkerWindows::Process()
{
int32_t success = 0;
DWORD ioSize = 0;
UdpSocket2Windows* pSocket = NULL;
PerIoContext* pIOContext = 0;
OVERLAPPED* pOverlapped = 0;
success = GetQueuedCompletionStatus(_ioCompletionHandle,
&ioSize,
(ULONG_PTR*)&pSocket, &pOverlapped, 200);
uint32_t error = 0;
if(!success)
{
error = GetLastError();
if(error == WAIT_TIMEOUT)
{
return true;
}
// This may happen if e.g. PostQueuedCompletionStatus() has been called.
// The IO context still needs to be reclaimed or re-used which is done
// in UdpSocket2Windows::IOCompleted(..).
}
if(pSocket == NULL)
{
WEBRTC_TRACE(
kTraceDebug,
kTraceTransport,
-1,
"UdpSocket2WorkerWindows(%d)::Process(), pSocket == 0, end thread",
_workerNumber);
return true;
}
pIOContext = (PerIoContext*)pOverlapped;
pSocket->IOCompleted(pIOContext,ioSize,error);
return true;
}
} // namespace test
} // namespace webrtc

View File

@ -1,162 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_
#include <winsock2.h>
#include <list>
#include "webrtc/system_wrappers/include/atomic32.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/base/platform_thread.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket2_win.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h"
#include "webrtc/voice_engine/test/channel_transport/udp_transport.h"
#define MAX_IO_BUFF_SIZE 1600
namespace webrtc {
namespace test {
enum IO_OPERATION {
OP_READ,
OP_WRITE
};
class UdpSocket2Windows;
// Struct used for all socket I/O operations.
struct PerIoContext {
WSAOVERLAPPED overlapped;
char buffer[MAX_IO_BUFF_SIZE];
WSABUF wsabuf;
size_t nTotalBytes;
int nSentBytes;
int bytes;
IO_OPERATION ioOperation;
SocketAddress from;
int fromLen;
// Should be set to true if the I/O context was passed to the system by
// a thread not controlled by the socket implementation.
bool ioInitiatedByPlatformThread;
// TODO (hellner): Not used. Delete it.
PerIoContext* pNextFree;
};
struct IoContextPoolItem;
struct IoContextPoolItemPayload
{
PerIoContext ioContext;
IoContextPoolItem* base;
};
struct IoContextPoolItem
{
// Atomic single linked list entry header.
SLIST_ENTRY itemEntry;
// Atomic single linked list payload
IoContextPoolItemPayload payload;
};
class IoContextPool
{
public:
IoContextPool();
virtual ~IoContextPool();
virtual int32_t Init(uint32_t increaseSize = 128);
// Re-use an old unused IO context or create a new one.
virtual PerIoContext* PopIoContext();
virtual int32_t PushIoContext(PerIoContext* pIoContext);
virtual inline int32_t GetSize(uint32_t* inUse = 0)
{return _size.Value();}
virtual int32_t Free();
private:
// Sample code for use of msfts single linked atomic list can be found here:
// http://msdn.microsoft.com/en-us/library/ms686962(VS.85).aspx
// Atomic single linked list head.
PSLIST_HEADER _pListHead;
bool _init;
Atomic32 _size;
Atomic32 _inUse;
};
class UdpSocket2WorkerWindows
{
public:
UdpSocket2WorkerWindows(HANDLE ioCompletionHandle);
virtual ~UdpSocket2WorkerWindows();
virtual bool Start();
virtual bool Stop();
virtual int32_t Init();
protected:
static bool Run(void* obj);
bool Process();
private:
HANDLE _ioCompletionHandle;
rtc::PlatformThread _pThread;
static int32_t _numOfWorkers;
int32_t _workerNumber;
volatile bool _stop;
bool _init;
};
class UdpSocket2ManagerWindows : public UdpSocketManager
{
public:
UdpSocket2ManagerWindows();
virtual ~UdpSocket2ManagerWindows();
virtual bool Init(int32_t id, uint8_t& numOfWorkThreads);
virtual bool Start();
virtual bool Stop();
virtual inline bool AddSocket(UdpSocketWrapper* s)
{if(s) return AddSocketPrv(reinterpret_cast<UdpSocket2Windows*>(s));
return false;}
virtual bool RemoveSocket(UdpSocketWrapper* s)
{if(s) return RemoveSocketPrv(reinterpret_cast<UdpSocket2Windows*>(s));
return false;}
PerIoContext* PopIoContext(void);
int32_t PushIoContext(PerIoContext* pIoContext);
private:
typedef std::list<UdpSocket2WorkerWindows*> WorkerList;
bool StopWorkerThreads();
bool StartWorkerThreads();
bool AddSocketPrv(UdpSocket2Windows* s);
bool RemoveSocketPrv(UdpSocket2Windows* s);
static uint32_t _numOfActiveManagers;
static bool _wsaInit;
int32_t _id;
CriticalSectionWrapper* _pCrit;
int32_t _managerNumber;
volatile bool _stopped;
bool _init;
int32_t _numActiveSockets;
WorkerList _workerThreadsList;
EventWrapper* _event;
HANDLE _ioCompletionHandle;
IoContextPool _ioContextPool;
};
} // namespace test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_MANAGER_WINDOWS_H_

File diff suppressed because it is too large Load Diff

View File

@ -1,174 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_WINDOWS_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_WINDOWS_H_
// Disable deprication warning from traffic.h
#pragma warning(disable : 4995)
// Don't change include order for these header files.
#include <Winsock2.h>
#include <Ntddndis.h>
#include <traffic.h>
#include "webrtc/base/event.h"
#include "webrtc/system_wrappers/include/atomic32.h"
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/system_wrappers/include/rw_lock_wrapper.h"
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h"
namespace webrtc {
namespace test {
class UdpSocket2ManagerWindows;
class TrafficControlWindows;
struct PerIoContext;
class UdpSocket2Windows : public UdpSocketWrapper
{
public:
UdpSocket2Windows(const int32_t id, UdpSocketManager* mgr,
bool ipV6Enable = false, bool disableGQOS = false);
virtual ~UdpSocket2Windows();
bool ValidHandle() override;
bool SetCallback(CallbackObj, IncomingSocketCallback) override;
bool Bind(const SocketAddress& name) override;
bool SetSockopt(int32_t level,
int32_t optname,
const int8_t* optval,
int32_t optlen) override;
bool StartReceiving(const uint32_t receiveBuffers) override;
inline bool StartReceiving() override { return StartReceiving(8); }
bool StopReceiving() override;
int32_t SendTo(const int8_t* buf,
size_t len,
const SocketAddress& to) override;
void CloseBlocking() override;
SOCKET GetFd() { return _socket;}
bool SetQos(int32_t serviceType,
int32_t tokenRate,
int32_t bucketSize,
int32_t peekBandwith,
int32_t minPolicedSize,
int32_t maxSduSize,
const SocketAddress& stRemName,
int32_t overrideDSCP = 0) override;
int32_t SetTOS(const int32_t serviceType) override;
int32_t SetPCP(const int32_t pcp) override;
uint32_t ReceiveBuffers() override { return _receiveBuffers.Value(); }
protected:
void IOCompleted(PerIoContext* pIOContext, uint32_t ioSize, uint32_t error);
int32_t PostRecv();
// Use pIoContext to post a new WSARecvFrom(..).
int32_t PostRecv(PerIoContext* pIoContext);
private:
friend class UdpSocket2WorkerWindows;
// Set traffic control (TC) flow adding it the interface that matches this
// sockets address.
// A filter is created and added to the flow.
// The flow consists of:
// (1) QoS send and receive information (flow specifications).
// (2) A DS object (for specifying exact DSCP value).
// (3) Possibly a traffic object (for specifying exact 802.1p priority (PCP)
// value).
//
// dscp values:
// -1 don't change the current dscp value.
// 0 don't add any flow to TC, unless pcp is specified.
// 1-63 Add a flow to TC with the specified dscp value.
// pcp values:
// -2 Don't add pcp info to the flow, (3) will not be added.
// -1 Don't change the current value.
// 0-7 Add pcp info to the flow with the specified value,
// (3) will be added.
//
// If both dscp and pcp are -1 no flow will be created or added to TC.
// If dscp is 0 and pcp is 0-7 (1), (2) and (3) will be created.
// Note: input parameter values are assumed to be in valid range, checks
// must be done by caller.
int32_t SetTrafficControl(int32_t dscp, int32_t pcp,
const struct sockaddr_in* name,
FLOWSPEC* send = NULL,
FLOWSPEC* recv = NULL);
int32_t CreateFlowSpec(int32_t serviceType,
int32_t tokenRate,
int32_t bucketSize,
int32_t peekBandwith,
int32_t minPolicedSize,
int32_t maxSduSize, FLOWSPEC *f);
int32_t _id;
RWLockWrapper* _ptrCbRWLock;
IncomingSocketCallback _incomingCb;
CallbackObj _obj;
bool _qos;
SocketAddress _remoteAddr;
SOCKET _socket;
int32_t _iProtocol;
UdpSocket2ManagerWindows* _mgr;
Atomic32 _outstandingCalls;
Atomic32 _outstandingCallComplete;
volatile bool _terminate;
volatile bool _addedToMgr;
rtc::Event delete_event_;
RWLockWrapper* _ptrDestRWLock;
bool _outstandingCallsDisabled;
bool NewOutstandingCall();
void OutstandingCallCompleted();
void DisableNewOutstandingCalls();
void RemoveSocketFromManager();
// RWLockWrapper is used as a reference counter for the socket. Write lock
// is used for creating and deleting socket. Read lock is used for
// accessing the socket.
RWLockWrapper* _ptrSocketRWLock;
bool AquireSocket();
void ReleaseSocket();
bool InvalidateSocket();
// Traffic control handles and structure pointers.
HANDLE _clientHandle;
HANDLE _flowHandle;
HANDLE _filterHandle;
PTC_GEN_FLOW _flow;
// TrafficControlWindows implements TOS and PCP.
TrafficControlWindows* _gtc;
// Holds the current pcp value. Can be -2 or 0 - 7.
int _pcp;
Atomic32 _receiveBuffers;
};
} // namespace test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET2_WINDOWS_H_

View File

@ -1,392 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.h"
#include <stdio.h>
#include <strings.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "webrtc/system_wrappers/include/sleep.h"
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_posix.h"
namespace webrtc {
namespace test {
UdpSocketManagerPosix::UdpSocketManagerPosix()
: UdpSocketManager(),
_id(-1),
_critSect(CriticalSectionWrapper::CreateCriticalSection()),
_numberOfSocketMgr(-1),
_incSocketMgrNextTime(0),
_nextSocketMgrToAssign(0),
_socketMgr()
{
}
bool UdpSocketManagerPosix::Init(int32_t id, uint8_t& numOfWorkThreads) {
CriticalSectionScoped cs(_critSect);
if ((_id != -1) || (_numOfWorkThreads != 0)) {
assert(_id != -1);
assert(_numOfWorkThreads != 0);
return false;
}
_id = id;
_numberOfSocketMgr = numOfWorkThreads;
_numOfWorkThreads = numOfWorkThreads;
if(MAX_NUMBER_OF_SOCKET_MANAGERS_LINUX < _numberOfSocketMgr)
{
_numberOfSocketMgr = MAX_NUMBER_OF_SOCKET_MANAGERS_LINUX;
}
for(int i = 0;i < _numberOfSocketMgr; i++)
{
_socketMgr[i] = new UdpSocketManagerPosixImpl();
}
return true;
}
UdpSocketManagerPosix::~UdpSocketManagerPosix()
{
Stop();
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocketManagerPosix(%d)::UdpSocketManagerPosix()",
_numberOfSocketMgr);
for(int i = 0;i < _numberOfSocketMgr; i++)
{
delete _socketMgr[i];
}
delete _critSect;
}
bool UdpSocketManagerPosix::Start()
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocketManagerPosix(%d)::Start()",
_numberOfSocketMgr);
_critSect->Enter();
bool retVal = true;
for(int i = 0;i < _numberOfSocketMgr && retVal; i++)
{
retVal = _socketMgr[i]->Start();
}
if(!retVal)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocketManagerPosix(%d)::Start() error starting socket managers",
_numberOfSocketMgr);
}
_critSect->Leave();
return retVal;
}
bool UdpSocketManagerPosix::Stop()
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocketManagerPosix(%d)::Stop()",_numberOfSocketMgr);
_critSect->Enter();
bool retVal = true;
for(int i = 0; i < _numberOfSocketMgr && retVal; i++)
{
retVal = _socketMgr[i]->Stop();
}
if(!retVal)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocketManagerPosix(%d)::Stop() there are still active socket "
"managers",
_numberOfSocketMgr);
}
_critSect->Leave();
return retVal;
}
bool UdpSocketManagerPosix::AddSocket(UdpSocketWrapper* s)
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocketManagerPosix(%d)::AddSocket()",_numberOfSocketMgr);
_critSect->Enter();
bool retVal = _socketMgr[_nextSocketMgrToAssign]->AddSocket(s);
if(!retVal)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocketManagerPosix(%d)::AddSocket() failed to add socket to\
manager",
_numberOfSocketMgr);
}
// Distribute sockets on UdpSocketManagerPosixImpls in a round-robin
// fashion.
if(_incSocketMgrNextTime == 0)
{
_incSocketMgrNextTime++;
} else {
_incSocketMgrNextTime = 0;
_nextSocketMgrToAssign++;
if(_nextSocketMgrToAssign >= _numberOfSocketMgr)
{
_nextSocketMgrToAssign = 0;
}
}
_critSect->Leave();
return retVal;
}
bool UdpSocketManagerPosix::RemoveSocket(UdpSocketWrapper* s)
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocketManagerPosix(%d)::RemoveSocket()",
_numberOfSocketMgr);
_critSect->Enter();
bool retVal = false;
for(int i = 0;i < _numberOfSocketMgr && (retVal == false); i++)
{
retVal = _socketMgr[i]->RemoveSocket(s);
}
if(!retVal)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
_id,
"UdpSocketManagerPosix(%d)::RemoveSocket() failed to remove socket\
from manager",
_numberOfSocketMgr);
}
_critSect->Leave();
return retVal;
}
UdpSocketManagerPosixImpl::UdpSocketManagerPosixImpl()
: _thread(UdpSocketManagerPosixImpl::Run,
this,
"UdpSocketManagerPosixImplThread"),
_critSectList(CriticalSectionWrapper::CreateCriticalSection()) {
FD_ZERO(&_readFds);
WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1,
"UdpSocketManagerPosix created");
}
UdpSocketManagerPosixImpl::~UdpSocketManagerPosixImpl()
{
if (_critSectList != NULL)
{
UpdateSocketMap();
_critSectList->Enter();
for (std::map<SOCKET, UdpSocketPosix*>::iterator it =
_socketMap.begin();
it != _socketMap.end();
++it) {
delete it->second;
}
_socketMap.clear();
_critSectList->Leave();
delete _critSectList;
}
WEBRTC_TRACE(kTraceMemory, kTraceTransport, -1,
"UdpSocketManagerPosix deleted");
}
bool UdpSocketManagerPosixImpl::Start()
{
WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1,
"Start UdpSocketManagerPosix");
_thread.Start();
_thread.SetPriority(rtc::kRealtimePriority);
return true;
}
bool UdpSocketManagerPosixImpl::Stop()
{
WEBRTC_TRACE(kTraceStateInfo, kTraceTransport, -1,
"Stop UdpSocketManagerPosix");
_thread.Stop();
return true;
}
bool UdpSocketManagerPosixImpl::Process()
{
bool doSelect = false;
// Timeout = 1 second.
struct timeval timeout;
timeout.tv_sec = 0;
timeout.tv_usec = 10000;
FD_ZERO(&_readFds);
UpdateSocketMap();
SOCKET maxFd = 0;
for (std::map<SOCKET, UdpSocketPosix*>::iterator it = _socketMap.begin();
it != _socketMap.end();
++it) {
doSelect = true;
if (it->first > maxFd)
maxFd = it->first;
FD_SET(it->first, &_readFds);
}
int num = 0;
if (doSelect)
{
num = select(maxFd+1, &_readFds, NULL, NULL, &timeout);
if (num == SOCKET_ERROR)
{
// Timeout = 10 ms.
SleepMs(10);
return true;
}
}else
{
// Timeout = 10 ms.
SleepMs(10);
return true;
}
for (std::map<SOCKET, UdpSocketPosix*>::iterator it = _socketMap.begin();
it != _socketMap.end();
++it) {
if (FD_ISSET(it->first, &_readFds)) {
it->second->HasIncoming();
--num;
}
}
return true;
}
bool UdpSocketManagerPosixImpl::Run(void* obj)
{
UdpSocketManagerPosixImpl* mgr =
static_cast<UdpSocketManagerPosixImpl*>(obj);
return mgr->Process();
}
bool UdpSocketManagerPosixImpl::AddSocket(UdpSocketWrapper* s)
{
UdpSocketPosix* sl = static_cast<UdpSocketPosix*>(s);
if(sl->GetFd() == INVALID_SOCKET || !(sl->GetFd() < FD_SETSIZE))
{
return false;
}
_critSectList->Enter();
_addList.push_back(s);
_critSectList->Leave();
return true;
}
bool UdpSocketManagerPosixImpl::RemoveSocket(UdpSocketWrapper* s)
{
// Put in remove list if this is the correct UdpSocketManagerPosixImpl.
_critSectList->Enter();
// If the socket is in the add list it's safe to remove and delete it.
for (SocketList::iterator iter = _addList.begin();
iter != _addList.end(); ++iter) {
UdpSocketPosix* addSocket = static_cast<UdpSocketPosix*>(*iter);
unsigned int addFD = addSocket->GetFd();
unsigned int removeFD = static_cast<UdpSocketPosix*>(s)->GetFd();
if(removeFD == addFD)
{
_removeList.push_back(removeFD);
_critSectList->Leave();
return true;
}
}
// Checking the socket map is safe since all Erase and Insert calls to this
// map are also protected by _critSectList.
if (_socketMap.find(static_cast<UdpSocketPosix*>(s)->GetFd()) !=
_socketMap.end()) {
_removeList.push_back(static_cast<UdpSocketPosix*>(s)->GetFd());
_critSectList->Leave();
return true;
}
_critSectList->Leave();
return false;
}
void UdpSocketManagerPosixImpl::UpdateSocketMap()
{
// Remove items in remove list.
_critSectList->Enter();
for (FdList::iterator iter = _removeList.begin();
iter != _removeList.end(); ++iter) {
UdpSocketPosix* deleteSocket = NULL;
SOCKET removeFD = *iter;
// If the socket is in the add list it hasn't been added to the socket
// map yet. Just remove the socket from the add list.
for (SocketList::iterator iter = _addList.begin();
iter != _addList.end(); ++iter) {
UdpSocketPosix* addSocket = static_cast<UdpSocketPosix*>(*iter);
SOCKET addFD = addSocket->GetFd();
if(removeFD == addFD)
{
deleteSocket = addSocket;
_addList.erase(iter);
break;
}
}
// Find and remove socket from _socketMap.
std::map<SOCKET, UdpSocketPosix*>::iterator it =
_socketMap.find(removeFD);
if(it != _socketMap.end())
{
deleteSocket = it->second;
_socketMap.erase(it);
}
if(deleteSocket)
{
deleteSocket->ReadyForDeletion();
delete deleteSocket;
}
}
_removeList.clear();
// Add sockets from add list.
for (SocketList::iterator iter = _addList.begin();
iter != _addList.end(); ++iter) {
UdpSocketPosix* s = static_cast<UdpSocketPosix*>(*iter);
if(s) {
_socketMap[s->GetFd()] = s;
}
}
_addList.clear();
_critSectList->Leave();
}
} // namespace test
} // namespace webrtc

View File

@ -1,88 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_POSIX_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_POSIX_H_
#include <sys/types.h>
#include <unistd.h>
#include <list>
#include <map>
#include "webrtc/base/platform_thread.h"
#include "webrtc/system_wrappers/include/critical_section_wrapper.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h"
namespace webrtc {
namespace test {
class UdpSocketPosix;
class UdpSocketManagerPosixImpl;
#define MAX_NUMBER_OF_SOCKET_MANAGERS_LINUX 8
class UdpSocketManagerPosix : public UdpSocketManager
{
public:
UdpSocketManagerPosix();
virtual ~UdpSocketManagerPosix();
bool Init(int32_t id, uint8_t& numOfWorkThreads) override;
bool Start() override;
bool Stop() override;
bool AddSocket(UdpSocketWrapper* s) override;
bool RemoveSocket(UdpSocketWrapper* s) override;
private:
int32_t _id;
CriticalSectionWrapper* _critSect;
uint8_t _numberOfSocketMgr;
uint8_t _incSocketMgrNextTime;
uint8_t _nextSocketMgrToAssign;
UdpSocketManagerPosixImpl* _socketMgr[MAX_NUMBER_OF_SOCKET_MANAGERS_LINUX];
};
class UdpSocketManagerPosixImpl
{
public:
UdpSocketManagerPosixImpl();
virtual ~UdpSocketManagerPosixImpl();
virtual bool Start();
virtual bool Stop();
virtual bool AddSocket(UdpSocketWrapper* s);
virtual bool RemoveSocket(UdpSocketWrapper* s);
protected:
static bool Run(void* obj);
bool Process();
void UpdateSocketMap();
private:
typedef std::list<UdpSocketWrapper*> SocketList;
typedef std::list<SOCKET> FdList;
rtc::PlatformThread _thread;
CriticalSectionWrapper* _critSectList;
fd_set _readFds;
std::map<SOCKET, UdpSocketPosix*> _socketMap;
SocketList _addList;
FdList _removeList;
};
} // namespace test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_POSIX_H_

View File

@ -1,84 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Tests for the UdpSocketManager interface.
// Note: This tests UdpSocketManager together with UdpSocketWrapper,
// due to the way the code is full of static-casts to the platform dependent
// subtypes.
// It also uses the static UdpSocketManager object.
// The most important property of these tests is that they do not leak memory.
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/test/gtest.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h"
namespace webrtc {
namespace test {
TEST(UdpSocketManager, CreateCallsInitAndDoesNotLeakMemory) {
int32_t id = 42;
uint8_t threads = 1;
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
// Create is supposed to have called init on the object.
EXPECT_FALSE(mgr->Init(id, threads))
<< "Init should return false since Create is supposed to call it.";
UdpSocketManager::Return();
}
// Creates a socket and adds it to the socket manager, and then removes it
// before destroying the socket manager.
TEST(UdpSocketManager, AddAndRemoveSocketDoesNotLeakMemory) {
int32_t id = 42;
uint8_t threads = 1;
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
UdpSocketWrapper* socket =
UdpSocketWrapper::CreateSocket(id,
mgr,
NULL, // CallbackObj
NULL, // IncomingSocketCallback
false, // ipV6Enable
false); // disableGQOS
// The constructor will do AddSocket on the manager.
// RemoveSocket indirectly calls Delete.
EXPECT_EQ(true, mgr->RemoveSocket(socket));
UdpSocketManager::Return();
}
// Creates a socket and add it to the socket manager, but does not remove it
// before destroying the socket manager.
// On Posix, this destroys the socket.
// On Winsock2 Windows, it enters an infinite wait for all the sockets
// to go away.
TEST(UdpSocketManager, UnremovedSocketsGetCollectedAtManagerDeletion) {
#if defined(_WIN32)
// It's hard to test an infinite wait, so we don't.
#else
int32_t id = 42;
uint8_t threads = 1;
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
UdpSocketWrapper* unused_socket = UdpSocketWrapper::CreateSocket(
id,
mgr,
NULL, // CallbackObj
NULL, // IncomingSocketCallback
false, // ipV6Enable
false); // disableGQOS
// The constructor will do AddSocket on the manager.
// Call a member funtion to work around "set but not used" compliation
// error on ChromeOS ARM.
unused_socket->SetEventToNull();
unused_socket = NULL;
UdpSocketManager::Return();
#endif
}
} // namespace test
} // namespace webrtc

View File

@ -1,72 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h"
#include <assert.h>
#ifdef _WIN32
#include "webrtc/system_wrappers/include/fix_interlocked_exchange_pointer_win.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket2_manager_win.h"
#else
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_posix.h"
#endif
namespace webrtc {
namespace test {
UdpSocketManager* UdpSocketManager::CreateInstance()
{
#if defined(_WIN32)
return static_cast<UdpSocketManager*>(new UdpSocket2ManagerWindows());
#else
return new UdpSocketManagerPosix();
#endif
}
UdpSocketManager* UdpSocketManager::StaticInstance(
CountOperation count_operation,
const int32_t id,
uint8_t& numOfWorkThreads)
{
UdpSocketManager* impl =
GetStaticInstance<UdpSocketManager>(count_operation);
if (count_operation == kAddRef && impl != NULL) {
if (impl->Init(id, numOfWorkThreads)) {
impl->Start();
}
}
return impl;
}
UdpSocketManager* UdpSocketManager::Create(const int32_t id,
uint8_t& numOfWorkThreads)
{
return UdpSocketManager::StaticInstance(kAddRef, id, numOfWorkThreads);
}
void UdpSocketManager::Return()
{
uint8_t numOfWorkThreads = 0;
UdpSocketManager::StaticInstance(kRelease, -1,
numOfWorkThreads);
}
UdpSocketManager::UdpSocketManager() : _numOfWorkThreads(0)
{
}
uint8_t UdpSocketManager::WorkThreads() const
{
return _numOfWorkThreads;
}
} // namespace test
} // namespace webrtc

View File

@ -1,70 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_WRAPPER_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_WRAPPER_H_
#include "webrtc/system_wrappers/include/static_instance.h"
#include "webrtc/typedefs.h"
namespace webrtc {
namespace test {
class UdpSocketWrapper;
class UdpSocketManager
{
public:
static UdpSocketManager* Create(const int32_t id,
uint8_t& numOfWorkThreads);
static void Return();
// Initializes the socket manager. Returns true if the manager wasn't
// already initialized.
virtual bool Init(int32_t id, uint8_t& numOfWorkThreads) = 0;
// Start listening to sockets that have been registered via the
// AddSocket(..) API.
virtual bool Start() = 0;
// Stop listening to sockets.
virtual bool Stop() = 0;
virtual uint8_t WorkThreads() const;
// Register a socket with the socket manager.
virtual bool AddSocket(UdpSocketWrapper* s) = 0;
// Unregister a socket from the manager.
virtual bool RemoveSocket(UdpSocketWrapper* s) = 0;
protected:
UdpSocketManager();
virtual ~UdpSocketManager() {}
uint8_t _numOfWorkThreads;
// Factory method.
static UdpSocketManager* CreateInstance();
private:
// Friend function to allow the UDP destructor to be accessed from the
// instance template.
friend UdpSocketManager* webrtc::GetStaticInstance<UdpSocketManager>(
CountOperation count_operation);
static UdpSocketManager* StaticInstance(
CountOperation count_operation,
const int32_t id,
uint8_t& numOfWorkThreads);
};
} // namespace test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_MANAGER_WRAPPER_H_

View File

@ -1,271 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/voice_engine/test/channel_transport/udp_socket_posix.h"
#include <errno.h>
#include <fcntl.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h"
namespace webrtc {
namespace test {
UdpSocketPosix::UdpSocketPosix(const int32_t id, UdpSocketManager* mgr,
bool ipV6Enable)
: _id(id),
_closeBlockingCompletedCond(true, false),
_readyForDeletionCond(true, false)
{
WEBRTC_TRACE(kTraceMemory, kTraceTransport, id,
"UdpSocketPosix::UdpSocketPosix()");
_wantsIncoming = false;
_mgr = mgr;
_obj = NULL;
_incomingCb = NULL;
_readyForDeletion = false;
_closeBlockingActive = false;
_closeBlockingCompleted = false;
if(ipV6Enable)
{
_socket = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
}
else {
_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
}
// Set socket to nonblocking mode.
int enable_non_blocking = 1;
if(ioctl(_socket, FIONBIO, &enable_non_blocking) == -1)
{
WEBRTC_TRACE(kTraceWarning, kTraceTransport, id,
"Failed to make socket nonblocking");
}
// Enable close on fork for file descriptor so that it will not block until
// forked process terminates.
if(fcntl(_socket, F_SETFD, FD_CLOEXEC) == -1)
{
WEBRTC_TRACE(kTraceWarning, kTraceTransport, id,
"Failed to set FD_CLOEXEC for socket");
}
}
UdpSocketPosix::~UdpSocketPosix()
{
if(_socket != INVALID_SOCKET)
{
close(_socket);
_socket = INVALID_SOCKET;
}
}
bool UdpSocketPosix::SetCallback(CallbackObj obj, IncomingSocketCallback cb)
{
_obj = obj;
_incomingCb = cb;
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocketPosix(%p)::SetCallback", this);
if (_mgr->AddSocket(this))
{
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocketPosix(%p)::SetCallback socket added to manager",
this);
return true; // socket is now ready for action
}
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"UdpSocketPosix(%p)::SetCallback error adding me to mgr",
this);
return false;
}
bool UdpSocketPosix::SetSockopt(int32_t level, int32_t optname,
const int8_t* optval, int32_t optlen)
{
if(0 == setsockopt(_socket, level, optname, optval, optlen ))
{
return true;
}
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
"UdpSocketPosix::SetSockopt(), error:%d", errno);
return false;
}
int32_t UdpSocketPosix::SetTOS(int32_t serviceType)
{
if (SetSockopt(IPPROTO_IP, IP_TOS ,(int8_t*)&serviceType ,4) != 0)
{
return -1;
}
return 0;
}
bool UdpSocketPosix::Bind(const SocketAddress& name)
{
int size = sizeof(sockaddr);
if (0 == bind(_socket, reinterpret_cast<const sockaddr*>(&name),size))
{
return true;
}
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
"UdpSocketPosix::Bind() error: %d", errno);
return false;
}
int32_t UdpSocketPosix::SendTo(const int8_t* buf, size_t len,
const SocketAddress& to)
{
int size = sizeof(sockaddr);
int retVal = sendto(_socket,buf, len, 0,
reinterpret_cast<const sockaddr*>(&to), size);
if(retVal == SOCKET_ERROR)
{
WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
"UdpSocketPosix::SendTo() error: %d", errno);
}
return retVal;
}
SOCKET UdpSocketPosix::GetFd() { return _socket; }
bool UdpSocketPosix::ValidHandle()
{
return _socket != INVALID_SOCKET;
}
bool UdpSocketPosix::SetQos(int32_t /*serviceType*/,
int32_t /*tokenRate*/,
int32_t /*bucketSize*/,
int32_t /*peekBandwith*/,
int32_t /*minPolicedSize*/,
int32_t /*maxSduSize*/,
const SocketAddress& /*stRemName*/,
int32_t /*overrideDSCP*/) {
return false;
}
void UdpSocketPosix::HasIncoming()
{
// replace 2048 with a mcro define and figure out
// where 2048 comes from
int8_t buf[2048];
int retval;
SocketAddress from;
#if defined(WEBRTC_MAC)
sockaddr sockaddrfrom;
memset(&from, 0, sizeof(from));
memset(&sockaddrfrom, 0, sizeof(sockaddrfrom));
socklen_t fromlen = sizeof(sockaddrfrom);
#else
memset(&from, 0, sizeof(from));
socklen_t fromlen = sizeof(from);
#endif
#if defined(WEBRTC_MAC)
retval = recvfrom(_socket,buf, sizeof(buf), 0,
reinterpret_cast<sockaddr*>(&sockaddrfrom), &fromlen);
memcpy(&from, &sockaddrfrom, fromlen);
from._sockaddr_storage.sin_family = sockaddrfrom.sa_family;
#else
retval = recvfrom(_socket,buf, sizeof(buf), 0,
reinterpret_cast<sockaddr*>(&from), &fromlen);
#endif
switch(retval)
{
case 0:
// The peer has performed an orderly shutdown.
break;
case SOCKET_ERROR:
break;
default:
if (_wantsIncoming && _incomingCb)
{
_incomingCb(_obj, buf, retval, &from);
}
break;
}
}
bool UdpSocketPosix::WantsIncoming() { return _wantsIncoming; }
void UdpSocketPosix::CloseBlocking()
{
rtc::CritScope lock(&_cs);
_closeBlockingActive = true;
if(!CleanUp())
{
_closeBlockingActive = false;
return;
}
if(!_readyForDeletion)
{
_cs.Leave();
_readyForDeletionCond.Wait(rtc::Event::kForever);
_cs.Enter();
}
_closeBlockingCompleted = true;
_closeBlockingCompletedCond.Set();
}
void UdpSocketPosix::ReadyForDeletion()
{
rtc::CritScope lock(&_cs);
if(!_closeBlockingActive)
{
return;
}
close(_socket);
_socket = INVALID_SOCKET;
_readyForDeletion = true;
_readyForDeletionCond.Set();
if(!_closeBlockingCompleted)
{
_cs.Leave();
_closeBlockingCompletedCond.Wait(rtc::Event::kForever);
_cs.Enter();
}
}
bool UdpSocketPosix::CleanUp()
{
_wantsIncoming = false;
if (_socket == INVALID_SOCKET)
{
return false;
}
WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
"calling UdpSocketManager::RemoveSocket()...");
_mgr->RemoveSocket(this);
// After this, the socket should may be or will be as deleted. Return
// immediately.
return true;
}
} // namespace test
} // namespace webrtc

View File

@ -1,94 +0,0 @@
/*
* Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_POSIX_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_POSIX_H_
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/types.h>
#include "webrtc/base/event.h"
#include "webrtc/base/criticalsection.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h"
namespace webrtc {
namespace test {
#define SOCKET_ERROR -1
class UdpSocketPosix : public UdpSocketWrapper
{
public:
UdpSocketPosix(const int32_t id, UdpSocketManager* mgr,
bool ipV6Enable = false);
virtual ~UdpSocketPosix();
bool SetCallback(CallbackObj obj, IncomingSocketCallback cb) override;
bool Bind(const SocketAddress& name) override;
bool SetSockopt(int32_t level,
int32_t optname,
const int8_t* optval,
int32_t optlen) override;
int32_t SetTOS(const int32_t serviceType) override;
int32_t SendTo(const int8_t* buf,
size_t len,
const SocketAddress& to) override;
// Deletes socket in addition to closing it.
// TODO (hellner): make destructor protected.
void CloseBlocking() override;
SOCKET GetFd();
bool ValidHandle() override;
bool SetQos(int32_t /*serviceType*/,
int32_t /*tokenRate*/,
int32_t /*bucketSize*/,
int32_t /*peekBandwith*/,
int32_t /*minPolicedSize*/,
int32_t /*maxSduSize*/,
const SocketAddress& /*stRemName*/,
int32_t /*overrideDSCP*/) override;
bool CleanUp();
void HasIncoming();
bool WantsIncoming();
void ReadyForDeletion();
private:
friend class UdpSocketManagerPosix;
const int32_t _id;
IncomingSocketCallback _incomingCb;
CallbackObj _obj;
SOCKET _socket;
UdpSocketManager* _mgr;
rtc::Event _closeBlockingCompletedCond;
rtc::Event _readyForDeletionCond;
bool _closeBlockingActive;
bool _closeBlockingCompleted;
bool _readyForDeletion;
rtc::CriticalSection _cs;
};
} // namespace test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_POSIX_H_

View File

@ -1,159 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h"
#include <stdlib.h>
#include <string.h>
#include "webrtc/system_wrappers/include/event_wrapper.h"
#include "webrtc/system_wrappers/include/trace.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h"
#if defined(_WIN32)
#include "webrtc/voice_engine/test/channel_transport/udp_socket2_win.h"
#else
#include "webrtc/voice_engine/test/channel_transport/udp_socket_posix.h"
#endif
namespace webrtc {
namespace test {
bool UdpSocketWrapper::_initiated = false;
// Temporary Android hack. The value 1024 is taken from
// <ndk>/build/platforms/android-1.5/arch-arm/usr/include/linux/posix_types.h
// TODO (tomasl): can we remove this now?
#ifndef FD_SETSIZE
#define FD_SETSIZE 1024
#endif
UdpSocketWrapper::UdpSocketWrapper()
: _wantsIncoming(false),
_deleteEvent(NULL)
{
}
UdpSocketWrapper::~UdpSocketWrapper()
{
if(_deleteEvent)
{
_deleteEvent->Set();
_deleteEvent = NULL;
}
}
void UdpSocketWrapper::SetEventToNull()
{
if (_deleteEvent)
{
_deleteEvent = NULL;
}
}
UdpSocketWrapper* UdpSocketWrapper::CreateSocket(const int32_t id,
UdpSocketManager* mgr,
CallbackObj obj,
IncomingSocketCallback cb,
bool ipV6Enable,
bool disableGQOS)
{
WEBRTC_TRACE(kTraceMemory, kTraceTransport, id,
"UdpSocketWrapper::CreateSocket");
UdpSocketWrapper* s = 0;
#ifdef _WIN32
if (!_initiated)
{
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD( 2, 2 );
int32_t err = WSAStartup( wVersionRequested, &wsaData);
if (err != 0)
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
id,
"UdpSocketWrapper::CreateSocket failed to initialize sockets\
WSAStartup error:%d",
err);
return NULL;
}
_initiated = true;
}
s = new UdpSocket2Windows(id, mgr, ipV6Enable, disableGQOS);
#else
if (!_initiated)
{
_initiated = true;
}
s = new UdpSocketPosix(id, mgr, ipV6Enable);
if (s)
{
UdpSocketPosix* sl = static_cast<UdpSocketPosix*>(s);
if (sl->GetFd() != INVALID_SOCKET && sl->GetFd() < FD_SETSIZE)
{
// ok
} else
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
id,
"UdpSocketWrapper::CreateSocket failed to initialize socket");
delete s;
s = NULL;
}
}
#endif
if (s)
{
s->_deleteEvent = NULL;
if (!s->SetCallback(obj, cb))
{
WEBRTC_TRACE(
kTraceError,
kTraceTransport,
id,
"UdpSocketWrapper::CreateSocket failed to ser callback");
return(NULL);
}
}
return s;
}
bool UdpSocketWrapper::StartReceiving()
{
_wantsIncoming = true;
return true;
}
bool UdpSocketWrapper::StartReceiving(const uint32_t /*receiveBuffers*/) {
return StartReceiving();
}
bool UdpSocketWrapper::StopReceiving()
{
_wantsIncoming = false;
return true;
}
int32_t UdpSocketWrapper::SetPCP(const int32_t /*pcp*/) { return -1; }
uint32_t UdpSocketWrapper::ReceiveBuffers() { return 0; }
} // namespace test
} // namespace webrtc

View File

@ -1,112 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_WRAPPER_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_WRAPPER_H_
#include "webrtc/voice_engine/test/channel_transport/udp_transport.h"
namespace webrtc {
class EventWrapper;
namespace test {
class UdpSocketManager;
#define SOCKET_ERROR_NO_QOS -1000
#ifndef _WIN32
typedef int SOCKET;
#endif
#ifndef INVALID_SOCKET
#define INVALID_SOCKET (SOCKET)(~0)
#ifndef AF_INET
#define AF_INET 2
#endif
#endif
typedef void* CallbackObj;
typedef void(*IncomingSocketCallback)(CallbackObj obj, const int8_t* buf,
size_t len, const SocketAddress* from);
class UdpSocketWrapper
{
public:
static UdpSocketWrapper* CreateSocket(const int32_t id,
UdpSocketManager* mgr,
CallbackObj obj,
IncomingSocketCallback cb,
bool ipV6Enable = false,
bool disableGQOS = false);
// Register cb for receiving callbacks when there are incoming packets.
// Register obj so that it will be passed in calls to cb.
virtual bool SetCallback(CallbackObj obj, IncomingSocketCallback cb) = 0;
// Socket to local address specified by name.
virtual bool Bind(const SocketAddress& name) = 0;
// Start receiving UDP data.
virtual bool StartReceiving();
virtual bool StartReceiving(const uint32_t /*receiveBuffers*/);
// Stop receiving UDP data.
virtual bool StopReceiving();
virtual bool ValidHandle() = 0;
// Set socket options.
virtual bool SetSockopt(int32_t level, int32_t optname,
const int8_t* optval, int32_t optlen) = 0;
// Set TOS for outgoing packets.
virtual int32_t SetTOS(const int32_t serviceType) = 0;
// Set 802.1Q PCP field (802.1p) for outgoing VLAN traffic.
virtual int32_t SetPCP(const int32_t /*pcp*/);
// Send buf of length len to the address specified by to.
virtual int32_t SendTo(const int8_t* buf, size_t len,
const SocketAddress& to) = 0;
virtual void SetEventToNull();
// Close socket and don't return until completed.
virtual void CloseBlocking() {}
// tokenRate is in bit/s. peakBandwidt is in byte/s
virtual bool SetQos(int32_t serviceType, int32_t tokenRate,
int32_t bucketSize, int32_t peekBandwith,
int32_t minPolicedSize, int32_t maxSduSize,
const SocketAddress &stRemName,
int32_t overrideDSCP = 0) = 0;
virtual uint32_t ReceiveBuffers();
protected:
// Creating the socket is done via CreateSocket().
UdpSocketWrapper();
// Destroying the socket is done via CloseBlocking().
virtual ~UdpSocketWrapper();
bool _wantsIncoming;
EventWrapper* _deleteEvent;
private:
static bool _initiated;
};
} // namespac test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_SOCKET_WRAPPER_H_

View File

@ -1,67 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// Tests for the UdpSocketWrapper interface.
// This will test the UdpSocket implementations on various platforms.
// Note that this test is using a real SocketManager, which starts up
// an extra worker thread, making the testing more complex than it
// should be.
// This is because on Posix, the CloseBlocking function waits for the
// ReadyForDeletion function to be called, which has to be called after
// CloseBlocking, and thus has to be called from another thread.
// The manager is the one actually doing the deleting.
// This is done differently in the Winsock2 code, but that code
// will also hang if the destructor is called directly.
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h"
#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h"
using ::testing::_;
using ::testing::Return;
namespace webrtc {
namespace test {
class MockSocketManager : public UdpSocketManager {
public:
MockSocketManager() {}
// Access to protected destructor.
void Destroy() {
delete this;
}
MOCK_METHOD2(Init, bool(int32_t, uint8_t&));
MOCK_METHOD0(Start, bool());
MOCK_METHOD0(Stop, bool());
MOCK_METHOD1(AddSocket, bool(UdpSocketWrapper*));
MOCK_METHOD1(RemoveSocket, bool(UdpSocketWrapper*));
};
// Creates a socket using the static constructor method and verifies that
// it's added to the socket manager.
TEST(UdpSocketWrapper, CreateSocket) {
int32_t id = 42;
// We can't test deletion of sockets without a socket manager.
uint8_t threads = 1;
UdpSocketManager* mgr = UdpSocketManager::Create(id, threads);
UdpSocketWrapper* socket =
UdpSocketWrapper::CreateSocket(id,
mgr,
NULL, // CallbackObj
NULL, // IncomingSocketCallback
false, // ipV6Enable
false); // disableGQOS
socket->CloseBlocking();
UdpSocketManager::Return();
}
} // namespace test
} // namespace webrtc

View File

@ -1,381 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_
#include "webrtc/api/call/transport.h"
#include "webrtc/common_types.h"
#include "webrtc/typedefs.h"
/*
* WARNING
* This code is not use in production/testing and might have security issues
* for example: http://code.google.com/p/webrtc/issues/detail?id=1028
*
*/
#define SS_MAXSIZE 128
#define SS_ALIGNSIZE (sizeof (uint64_t))
#define SS_PAD1SIZE (SS_ALIGNSIZE - sizeof(int16_t))
#define SS_PAD2SIZE (SS_MAXSIZE - (sizeof(int16_t) + SS_PAD1SIZE +\
SS_ALIGNSIZE))
// BSD requires use of HAVE_STRUCT_SOCKADDR_SA_LEN
namespace webrtc {
namespace test {
struct SocketAddressIn {
// sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
int8_t sin_length;
int8_t sin_family;
#else
int16_t sin_family;
#endif
uint16_t sin_port;
uint32_t sin_addr;
int8_t sin_zero[8];
};
struct Version6InAddress {
union {
uint8_t _s6_u8[16];
uint32_t _s6_u32[4];
uint64_t _s6_u64[2];
} Version6AddressUnion;
};
struct SocketAddressInVersion6 {
// sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
int8_t sin_length;
int8_t sin_family;
#else
int16_t sin_family;
#endif
// Transport layer port number.
uint16_t sin6_port;
// IPv6 traffic class and flow info or ip4 address.
uint32_t sin6_flowinfo;
// IPv6 address
struct Version6InAddress sin6_addr;
// Set of interfaces for a scope.
uint32_t sin6_scope_id;
};
struct SocketAddressStorage {
// sin_family should be either AF_INET (IPv4) or AF_INET6 (IPv6)
#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
int8_t sin_length;
int8_t sin_family;
#else
int16_t sin_family;
#endif
int8_t __ss_pad1[SS_PAD1SIZE];
uint64_t __ss_align;
int8_t __ss_pad2[SS_PAD2SIZE];
};
struct SocketAddress {
union {
struct SocketAddressIn _sockaddr_in;
struct SocketAddressInVersion6 _sockaddr_in6;
struct SocketAddressStorage _sockaddr_storage;
};
};
// Callback class that receives packets from UdpTransport.
class UdpTransportData {
public:
virtual ~UdpTransportData() {};
virtual void IncomingRTPPacket(const int8_t* incomingRtpPacket,
const size_t rtpPacketLength,
const char* fromIP,
const uint16_t fromPort) = 0;
virtual void IncomingRTCPPacket(const int8_t* incomingRtcpPacket,
const size_t rtcpPacketLength,
const char* fromIP,
const uint16_t fromPort) = 0;
};
class UdpTransport : public Transport {
public:
enum
{
kIpAddressVersion6Length = 64,
kIpAddressVersion4Length = 16
};
enum ErrorCode
{
kNoSocketError = 0,
kFailedToBindPort = 1,
kIpAddressInvalid = 2,
kAddressInvalid = 3,
kSocketInvalid = 4,
kPortInvalid = 5,
kTosInvalid = 6,
kMulticastAddressInvalid = 7,
kQosError = 8,
kSocketAlreadyInitialized = 9,
kIpVersion6Error = 10,
FILTER_ERROR = 11,
kStartReceiveError = 12,
kStopReceiveError = 13,
kCannotFindLocalIp = 14,
kTosError = 16,
kNotInitialized = 17,
kPcpError = 18
};
// Factory method. Constructor disabled.
static UdpTransport* Create(const int32_t id, uint8_t& numSocketThreads);
static void Destroy(UdpTransport* module);
// Prepares the class for sending RTP packets to ipAddr:rtpPort and RTCP
// packets to ipAddr:rtpPort+1 if rtcpPort is zero. Otherwise to
// ipAddr:rtcpPort.
virtual int32_t InitializeSendSockets(const char* ipAddr,
const uint16_t rtpPort,
const uint16_t rtcpPort = 0) = 0;
// Register packetCallback for receiving incoming packets. Set the local
// RTP port to rtpPort. Bind local IP address to ipAddr. If ipAddr is NULL
// bind to local IP ANY. Set the local rtcp port to rtcpPort or rtpPort + 1
// if rtcpPort is 0.
virtual int32_t InitializeReceiveSockets(
UdpTransportData* const packetCallback,
const uint16_t rtpPort,
const char* ipAddr = NULL,
const char* multicastIpAddr = NULL,
const uint16_t rtcpPort = 0) = 0;
// Set local RTP port to rtpPort and RTCP port to rtcpPort or rtpPort + 1 if
// rtcpPort is 0. These ports will be used for sending instead of the local
// ports set by InitializeReceiveSockets(..).
virtual int32_t InitializeSourcePorts(const uint16_t rtpPort,
const uint16_t rtcpPort = 0) = 0;
// Retrieve local ports used for sending if other than the ports specified
// by InitializeReceiveSockets(..). rtpPort is set to the RTP port.
// rtcpPort is set to the RTCP port.
virtual int32_t SourcePorts(uint16_t& rtpPort,
uint16_t& rtcpPort) const = 0;
// Set ipAddr to the IP address that is currently being listened on. rtpPort
// to the RTP port listened to. rtcpPort to the RTCP port listened on.
// multicastIpAddr to the multicast IP address group joined (the address
// is NULL terminated).
virtual int32_t ReceiveSocketInformation(
char ipAddr[kIpAddressVersion6Length],
uint16_t& rtpPort,
uint16_t& rtcpPort,
char multicastIpAddr[kIpAddressVersion6Length]) const = 0;
// Set ipAddr to the IP address being sent from. rtpPort to the local RTP
// port used for sending and rtcpPort to the local RTCP port used for
// sending.
virtual int32_t SendSocketInformation(char ipAddr[kIpAddressVersion6Length],
uint16_t& rtpPort,
uint16_t& rtcpPort) const = 0;
// Put the IP address, RTP port and RTCP port from the last received packet
// into ipAddr, rtpPort and rtcpPort respectively.
virtual int32_t RemoteSocketInformation(
char ipAddr[kIpAddressVersion6Length],
uint16_t& rtpPort,
uint16_t& rtcpPort) const = 0;
// Enable/disable quality of service if QoS is true or false respectively.
// Set the type of service to serviceType, max bitrate in kbit/s to
// maxBitrate and override DSCP if overrideDSCP is not 0.
// Note: Must be called both InitializeSendSockets() and
// InitializeReceiveSockets() has been called.
virtual int32_t SetQoS(const bool QoS,
const int32_t serviceType,
const uint32_t maxBitrate = 0,
const int32_t overrideDSCP = 0,
const bool audio = false) = 0;
// Set QoS to true if quality of service has been turned on. If QoS is true,
// also set serviceType to type of service and overrideDSCP to override
// DSCP.
virtual int32_t QoS(bool& QoS,
int32_t& serviceType,
int32_t& overrideDSCP) const = 0;
// Set type of service.
virtual int32_t SetToS(const int32_t DSCP,
const bool useSetSockOpt = false) = 0;
// Get type of service configuration.
virtual int32_t ToS(int32_t& DSCP,
bool& useSetSockOpt) const = 0;
// Set Priority Code Point (IEEE 802.1Q)
// Note: for Linux this function will set the priority for the socket,
// which then can be mapped to a PCP value with vconfig.
virtual int32_t SetPCP(const int32_t PCP) = 0;
// Get Priority Code Point
virtual int32_t PCP(int32_t& PCP) const = 0;
// Enable IPv6.
// Note: this API must be called before any call to
// InitializeReceiveSockets() or InitializeSendSockets(). It is not
// possible to go back to IPv4 (default) after this call.
virtual int32_t EnableIpV6() = 0;
// Return true if IPv6 has been enabled.
virtual bool IpV6Enabled() const = 0;
// Only allow packets received from filterIPAddress to be processed.
// Note: must be called after EnableIPv6(), if IPv6 is used.
virtual int32_t SetFilterIP(
const char filterIPAddress[kIpAddressVersion6Length]) = 0;
// Write the filter IP address (if any) to filterIPAddress.
virtual int32_t FilterIP(
char filterIPAddress[kIpAddressVersion6Length]) const = 0;
// Only allow RTP packets from rtpFilterPort and RTCP packets from
// rtcpFilterPort be processed.
// Note: must be called after EnableIPv6(), if IPv6 is used.
virtual int32_t SetFilterPorts(const uint16_t rtpFilterPort,
const uint16_t rtcpFilterPort) = 0;
// Set rtpFilterPort to the filter RTP port and rtcpFilterPort to the
// filter RTCP port (if filtering based on port is enabled).
virtual int32_t FilterPorts(uint16_t& rtpFilterPort,
uint16_t& rtcpFilterPort) const = 0;
// Set the number of buffers that the socket implementation may use for
// receiving packets to numberOfSocketBuffers. I.e. the number of packets
// that can be received in parallell.
// Note: this API only has effect on Windows.
virtual int32_t StartReceiving(const uint32_t numberOfSocketBuffers) = 0;
// Stop receive incoming packets.
virtual int32_t StopReceiving() = 0;
// Return true incoming packets are received.
virtual bool Receiving() const = 0;
// Return true if send sockets have been initialized.
virtual bool SendSocketsInitialized() const = 0;
// Return true if local ports for sending has been set.
virtual bool SourcePortsInitialized() const = 0;
// Return true if receive sockets have been initialized.
virtual bool ReceiveSocketsInitialized() const = 0;
// Send data with size length to ip:portnr. The same port as the set
// with InitializeSendSockets(..) is used if portnr is 0. The same IP
// address as set with InitializeSendSockets(..) is used if ip is NULL.
// If isRTCP is true the port used will be the RTCP port.
virtual int32_t SendRaw(const int8_t* data,
size_t length,
int32_t isRTCP,
uint16_t portnr = 0,
const char* ip = NULL) = 0;
// Send RTP data with size length to the address specified by to.
virtual int32_t SendRTPPacketTo(const int8_t* data,
size_t length,
const SocketAddress& to) = 0;
// Send RTCP data with size length to the address specified by to.
virtual int32_t SendRTCPPacketTo(const int8_t* data,
size_t length,
const SocketAddress& to) = 0;
// Send RTP data with size length to ip:rtpPort where ip is the ip set by
// the InitializeSendSockets(..) call.
virtual int32_t SendRTPPacketTo(const int8_t* data,
size_t length,
uint16_t rtpPort) = 0;
// Send RTCP data with size length to ip:rtcpPort where ip is the ip set by
// the InitializeSendSockets(..) call.
virtual int32_t SendRTCPPacketTo(const int8_t* data,
size_t length,
uint16_t rtcpPort) = 0;
// Set the IP address to which packets are sent to ipaddr.
virtual int32_t SetSendIP(
const char ipaddr[kIpAddressVersion6Length]) = 0;
// Set the send RTP and RTCP port to rtpPort and rtcpPort respectively.
virtual int32_t SetSendPorts(const uint16_t rtpPort,
const uint16_t rtcpPort = 0) = 0;
// Retreive the last registered error code.
virtual ErrorCode LastError() const = 0;
// Put the local IPv4 address in localIP.
// Note: this API is for IPv4 only.
static int32_t LocalHostAddress(uint32_t& localIP);
// Put the local IP6 address in localIP.
// Note: this API is for IPv6 only.
static int32_t LocalHostAddressIPV6(char localIP[16]);
// Return a copy of hostOrder (host order) in network order.
static uint16_t Htons(uint16_t hostOrder);
// Return a copy of hostOrder (host order) in network order.
static uint32_t Htonl(uint32_t hostOrder);
// Return IPv4 address in ip as 32 bit integer.
static uint32_t InetAddrIPV4(const char* ip);
// Convert the character string src into a network address structure in
// the af address family and put it in dst.
// Note: same functionality as inet_pton(..)
static int32_t InetPresentationToNumeric(int32_t af,
const char* src,
void* dst);
// Set ip and sourcePort according to address. As input parameter ipSize
// is the length of ip. As output parameter it's the number of characters
// written to ip (not counting the '\0' character).
// Note: this API is only implemented on Windows and Linux.
static int32_t IPAddress(const SocketAddress& address,
char* ip,
uint32_t& ipSize,
uint16_t& sourcePort);
// Set ip and sourcePort according to address. As input parameter ipSize
// is the length of ip. As output parameter it's the number of characters
// written to ip (not counting the '\0' character).
// Note: this API is only implemented on Windows and Linux.
// Additional note: this API caches the address of the last call to it. If
// address is likley to be the same for multiple calls it may be beneficial
// to call this API instead of IPAddress().
virtual int32_t IPAddressCached(const SocketAddress& address,
char* ip,
uint32_t& ipSize,
uint16_t& sourcePort) = 0;
// Return true if ipaddr is a valid IP address.
// If ipV6 is false ipaddr is interpreted as an IPv4 address otherwise it
// is interptreted as IPv6.
static bool IsIpAddressValid(const char* ipaddr, const bool ipV6);
};
} // namespace test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_H_

View File

@ -1,259 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_IMPL_H_
#define WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_IMPL_H_
#include "webrtc/voice_engine/test/channel_transport/udp_socket_wrapper.h"
#include "webrtc/voice_engine/test/channel_transport/udp_transport.h"
namespace webrtc {
class CriticalSectionWrapper;
class RWLockWrapper;
namespace test {
class UdpSocketManager;
class UdpTransportImpl : public UdpTransport
{
public:
// A factory that returns a wrapped UDP socket or equivalent.
class SocketFactoryInterface {
public:
virtual ~SocketFactoryInterface() {}
virtual UdpSocketWrapper* CreateSocket(const int32_t id,
UdpSocketManager* mgr,
CallbackObj obj,
IncomingSocketCallback cb,
bool ipV6Enable,
bool disableGQOS) = 0;
};
// Constructor, only called by UdpTransport::Create and tests.
// The constructor takes ownership of the "maker".
// The constructor does not take ownership of socket_manager.
UdpTransportImpl(const int32_t id,
SocketFactoryInterface* maker,
UdpSocketManager* socket_manager);
virtual ~UdpTransportImpl();
// UdpTransport functions
int32_t InitializeSendSockets(const char* ipAddr,
const uint16_t rtpPort,
const uint16_t rtcpPort = 0) override;
int32_t InitializeReceiveSockets(UdpTransportData* const packetCallback,
const uint16_t rtpPort,
const char* ipAddr = NULL,
const char* multicastIpAddr = NULL,
const uint16_t rtcpPort = 0) override;
int32_t InitializeSourcePorts(const uint16_t rtpPort,
const uint16_t rtcpPort = 0) override;
int32_t SourcePorts(uint16_t& rtpPort, uint16_t& rtcpPort) const override;
int32_t ReceiveSocketInformation(
char ipAddr[kIpAddressVersion6Length],
uint16_t& rtpPort,
uint16_t& rtcpPort,
char multicastIpAddr[kIpAddressVersion6Length]) const override;
int32_t SendSocketInformation(char ipAddr[kIpAddressVersion6Length],
uint16_t& rtpPort,
uint16_t& rtcpPort) const override;
int32_t RemoteSocketInformation(char ipAddr[kIpAddressVersion6Length],
uint16_t& rtpPort,
uint16_t& rtcpPort) const override;
int32_t SetQoS(const bool QoS,
const int32_t serviceType,
const uint32_t maxBitrate = 0,
const int32_t overrideDSCP = 0,
const bool audio = false) override;
int32_t QoS(bool& QoS,
int32_t& serviceType,
int32_t& overrideDSCP) const override;
int32_t SetToS(const int32_t DSCP,
const bool useSetSockOpt = false) override;
int32_t ToS(int32_t& DSCP, bool& useSetSockOpt) const override;
int32_t SetPCP(const int32_t PCP) override;
int32_t PCP(int32_t& PCP) const override;
int32_t EnableIpV6() override;
bool IpV6Enabled() const override;
int32_t SetFilterIP(
const char filterIPAddress[kIpAddressVersion6Length]) override;
int32_t FilterIP(
char filterIPAddress[kIpAddressVersion6Length]) const override;
int32_t SetFilterPorts(const uint16_t rtpFilterPort,
const uint16_t rtcpFilterPort) override;
int32_t FilterPorts(uint16_t& rtpFilterPort,
uint16_t& rtcpFilterPort) const override;
int32_t StartReceiving(const uint32_t numberOfSocketBuffers) override;
int32_t StopReceiving() override;
bool Receiving() const override;
bool SendSocketsInitialized() const override;
bool SourcePortsInitialized() const override;
bool ReceiveSocketsInitialized() const override;
int32_t SendRaw(const int8_t* data,
size_t length,
int32_t isRTCP,
uint16_t portnr = 0,
const char* ip = NULL) override;
int32_t SendRTPPacketTo(const int8_t* data,
size_t length,
const SocketAddress& to) override;
int32_t SendRTCPPacketTo(const int8_t* data,
size_t length,
const SocketAddress& to) override;
int32_t SendRTPPacketTo(const int8_t* data,
size_t length,
uint16_t rtpPort) override;
int32_t SendRTCPPacketTo(const int8_t* data,
size_t length,
uint16_t rtcpPort) override;
// Transport functions
bool SendRtp(const uint8_t* data,
size_t length,
const PacketOptions& packet_options) override;
bool SendRtcp(const uint8_t* data, size_t length) override;
// UdpTransport functions continue.
int32_t SetSendIP(const char* ipaddr) override;
int32_t SetSendPorts(const uint16_t rtpPort,
const uint16_t rtcpPort = 0) override;
ErrorCode LastError() const override;
int32_t IPAddressCached(const SocketAddress& address,
char* ip,
uint32_t& ipSize,
uint16_t& sourcePort) override;
int32_t Id() const {return _id;}
protected:
// IncomingSocketCallback signature functions for receiving callbacks from
// UdpSocketWrapper.
static void IncomingRTPCallback(CallbackObj obj,
const int8_t* rtpPacket,
size_t rtpPacketLength,
const SocketAddress* from);
static void IncomingRTCPCallback(CallbackObj obj,
const int8_t* rtcpPacket,
size_t rtcpPacketLength,
const SocketAddress* from);
void CloseSendSockets();
void CloseReceiveSockets();
// Update _remoteRTPAddr according to _destPort and _destIP
void BuildRemoteRTPAddr();
// Update _remoteRTCPAddr according to _destPortRTCP and _destIP
void BuildRemoteRTCPAddr();
void BuildSockaddrIn(uint16_t portnr, const char* ip,
SocketAddress& remoteAddr) const;
ErrorCode BindLocalRTPSocket();
ErrorCode BindLocalRTCPSocket();
ErrorCode BindRTPSendSocket();
ErrorCode BindRTCPSendSocket();
void IncomingRTPFunction(const int8_t* rtpPacket,
size_t rtpPacketLength,
const SocketAddress* from);
void IncomingRTCPFunction(const int8_t* rtcpPacket,
size_t rtcpPacketLength,
const SocketAddress* from);
bool FilterIPAddress(const SocketAddress* fromAddress);
bool SetSockOptUsed();
int32_t EnableQoS(int32_t serviceType, bool audio,
uint32_t maxBitrate, int32_t overrideDSCP);
int32_t DisableQoS();
private:
void GetCachedAddress(char* ip, uint32_t& ipSize,
uint16_t& sourcePort);
int32_t _id;
SocketFactoryInterface* _socket_creator;
// Protects the sockets from being re-configured while receiving packets.
CriticalSectionWrapper* _crit;
CriticalSectionWrapper* _critFilter;
// _packetCallback's critical section.
CriticalSectionWrapper* _critPacketCallback;
UdpSocketManager* _mgr;
ErrorCode _lastError;
// Remote RTP and RTCP ports.
uint16_t _destPort;
uint16_t _destPortRTCP;
// Local RTP and RTCP ports.
uint16_t _localPort;
uint16_t _localPortRTCP;
// Local port number when the local port for receiving and local port number
// for sending are not the same.
uint16_t _srcPort;
uint16_t _srcPortRTCP;
// Remote port from which last received packet was sent.
uint16_t _fromPort;
uint16_t _fromPortRTCP;
char _fromIP[kIpAddressVersion6Length];
char _destIP[kIpAddressVersion6Length];
char _localIP[kIpAddressVersion6Length];
char _localMulticastIP[kIpAddressVersion6Length];
UdpSocketWrapper* _ptrRtpSocket;
UdpSocketWrapper* _ptrRtcpSocket;
// Local port when the local port for receiving and local port for sending
// are not the same.
UdpSocketWrapper* _ptrSendRtpSocket;
UdpSocketWrapper* _ptrSendRtcpSocket;
SocketAddress _remoteRTPAddr;
SocketAddress _remoteRTCPAddr;
SocketAddress _localRTPAddr;
SocketAddress _localRTCPAddr;
int32_t _tos;
bool _receiving;
bool _useSetSockOpt;
bool _qos;
int32_t _pcp;
bool _ipV6Enabled;
int32_t _serviceType;
int32_t _overrideDSCP;
uint32_t _maxBitrate;
// Cache used by GetCachedAddress(..).
RWLockWrapper* _cachLock;
SocketAddress _previousAddress;
char _previousIP[kIpAddressVersion6Length];
uint32_t _previousIPSize;
uint16_t _previousSourcePort;
SocketAddress _filterIPAddress;
uint16_t _rtpFilterPort;
uint16_t _rtcpFilterPort;
UdpTransportData* _packetCallback;
};
} // namespace test
} // namespace webrtc
#endif // WEBRTC_VOICE_ENGINE_TEST_CHANNEL_TRANSPORT_UDP_TRANSPORT_IMPL_H_

View File

@ -1,145 +0,0 @@
/*
* Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#include <vector>
#include "webrtc/test/gmock.h"
#include "webrtc/test/gtest.h"
#include "webrtc/voice_engine/test/channel_transport/udp_transport.h"
// We include the implementation header file to get at the dependency-injecting
// constructor.
#include "webrtc/voice_engine/test/channel_transport/udp_transport_impl.h"
// We must mock the socket manager, for which we need its definition.
#include "webrtc/voice_engine/test/channel_transport/udp_socket_manager_wrapper.h"
using ::testing::_;
using ::testing::Return;
namespace webrtc {
namespace test {
class MockUdpSocketWrapper : public UdpSocketWrapper {
public:
// The following methods have to be mocked because they are pure.
MOCK_METHOD2(SetCallback, bool(CallbackObj, IncomingSocketCallback));
MOCK_METHOD1(Bind, bool(const SocketAddress&));
MOCK_METHOD0(ValidHandle, bool());
MOCK_METHOD4(SetSockopt, bool(int32_t, int32_t,
const int8_t*,
int32_t));
MOCK_METHOD1(SetTOS, int32_t(int32_t));
MOCK_METHOD3(SendTo, int32_t(const int8_t*, size_t, const SocketAddress&));
MOCK_METHOD8(SetQos, bool(int32_t, int32_t,
int32_t, int32_t,
int32_t, int32_t,
const SocketAddress &,
int32_t));
};
class MockUdpSocketManager : public UdpSocketManager {
public:
// Access to protected destructor.
void Destroy() {
delete this;
}
MOCK_METHOD2(Init, bool(int32_t, uint8_t&));
MOCK_METHOD0(Start, bool());
MOCK_METHOD0(Stop, bool());
MOCK_METHOD1(AddSocket, bool(UdpSocketWrapper*));
MOCK_METHOD1(RemoveSocket, bool(UdpSocketWrapper*));
};
class MockSocketFactory :
public UdpTransportImpl::SocketFactoryInterface {
public:
MockSocketFactory(std::vector<MockUdpSocketWrapper*>* socket_counter)
: socket_counter_(socket_counter) {
}
UdpSocketWrapper* CreateSocket(const int32_t id,
UdpSocketManager* mgr,
CallbackObj obj,
IncomingSocketCallback cb,
bool ipV6Enable,
bool disableGQOS) {
MockUdpSocketWrapper* socket = new MockUdpSocketWrapper();
// We instrument the socket with calls that are expected, but do
// not matter for any specific test, in order to avoid warning messages.
EXPECT_CALL(*socket, ValidHandle()).WillRepeatedly(Return(true));
EXPECT_CALL(*socket, Bind(_)).WillOnce(Return(true));
socket_counter_->push_back(socket);
return socket;
}
std::vector<MockUdpSocketWrapper*>* socket_counter_;
};
class UDPTransportTest : public ::testing::Test {
public:
UDPTransportTest()
: sockets_created_(0) {
}
~UDPTransportTest() {
// In production, sockets register themselves at creation time with
// an UdpSocketManager, and the UdpSocketManager is responsible for
// deleting them. In this test, we just delete them after the test.
while (!sockets_created_.empty()) {
delete sockets_created_.back();
sockets_created_.pop_back();
}
}
size_t NumSocketsCreated() {
return sockets_created_.size();
}
std::vector<MockUdpSocketWrapper*>* sockets_created() {
return &sockets_created_;
}
private:
std::vector<MockUdpSocketWrapper*> sockets_created_;
};
TEST_F(UDPTransportTest, CreateTransport) {
int32_t id = 0;
uint8_t threads = 1;
UdpTransport* transport = UdpTransport::Create(id, threads);
UdpTransport::Destroy(transport);
}
// This test verifies that the mock_socket is not called from the constructor.
TEST_F(UDPTransportTest, ConstructorDoesNotCreateSocket) {
int32_t id = 0;
UdpTransportImpl::SocketFactoryInterface* null_maker = NULL;
UdpSocketManager* null_manager = NULL;
UdpTransport* transport = new UdpTransportImpl(id,
null_maker,
null_manager);
delete transport;
}
TEST_F(UDPTransportTest, InitializeSourcePorts) {
int32_t id = 0;
UdpTransportImpl::SocketFactoryInterface* mock_maker
= new MockSocketFactory(sockets_created());
MockUdpSocketManager* mock_manager = new MockUdpSocketManager();
UdpTransport* transport = new UdpTransportImpl(id,
mock_maker,
mock_manager);
EXPECT_EQ(0, transport->InitializeSourcePorts(4711, 4712));
EXPECT_EQ(2u, NumSocketsCreated());
delete transport;
mock_manager->Destroy();
}
} // namespace test
} // namespace webrtc