1/*
2 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
12#include "webrtc/system_wrappers/interface/event_wrapper.h"
13#include "webrtc/system_wrappers/interface/sleep.h"
14#include "webrtc/system_wrappers/interface/thread_wrapper.h"
15#include "webrtc/voice_engine/include/voe_network.h"
16#include "webrtc/voice_engine/test/auto_test/fakes/fake_external_transport.h"
17#include "webrtc/voice_engine/voice_engine_defines.h"
18
19FakeExternalTransport::FakeExternalTransport(webrtc::VoENetwork* ptr)
20    : my_network_(ptr),
21      thread_(NULL),
22      lock_(NULL),
23      event_(NULL),
24      length_(0),
25      channel_(0),
26      delay_is_enabled_(0),
27      delay_time_in_ms_(0) {
28  const char* thread_name = "external_thread";
29  lock_ = webrtc::CriticalSectionWrapper::CreateCriticalSection();
30  event_ = webrtc::EventWrapper::Create();
31  thread_ = webrtc::ThreadWrapper::CreateThread(
32      Run, this, webrtc::kHighPriority, thread_name);
33  if (thread_) {
34    unsigned int id;
35    thread_->Start(id);
36  }
37}
38
39FakeExternalTransport::~FakeExternalTransport() {
40  if (thread_) {
41    thread_->SetNotAlive();
42    event_->Set();
43    if (thread_->Stop()) {
44      delete thread_;
45      thread_ = NULL;
46      delete event_;
47      event_ = NULL;
48      delete lock_;
49      lock_ = NULL;
50    }
51  }
52}
53
54bool FakeExternalTransport::Run(void* ptr) {
55  return static_cast<FakeExternalTransport*> (ptr)->Process();
56}
57
58bool FakeExternalTransport::Process() {
59  switch (event_->Wait(500)) {
60    case webrtc::kEventSignaled:
61      lock_->Enter();
62      my_network_->ReceivedRTPPacket(channel_, packet_buffer_, length_,
63                                     webrtc::PacketTime());
64      lock_->Leave();
65      return true;
66    case webrtc::kEventTimeout:
67      return true;
68    case webrtc::kEventError:
69      break;
70  }
71  return true;
72}
73
74int FakeExternalTransport::SendPacket(int channel, const void *data, int len) {
75  lock_->Enter();
76  if (len < 1612) {
77    memcpy(packet_buffer_, (const unsigned char*) data, len);
78    length_ = len;
79    channel_ = channel;
80  }
81  lock_->Leave();
82  event_->Set();  // Triggers ReceivedRTPPacket() from worker thread.
83  return len;
84}
85
86int FakeExternalTransport::SendRTCPPacket(int channel,
87                                          const void *data,
88                                          int len) {
89  if (delay_is_enabled_) {
90    webrtc::SleepMs(delay_time_in_ms_);
91  }
92  my_network_->ReceivedRTCPPacket(channel, data, len);
93  return len;
94}
95
96void FakeExternalTransport::SetDelayStatus(bool enable,
97                                           unsigned int delayInMs) {
98  delay_is_enabled_ = enable;
99  delay_time_in_ms_ = delayInMs;
100}
101