1/*
2 *  Copyright (c) 2013 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#include "webrtc/test/direct_transport.h"
11
12#include "testing/gtest/include/gtest/gtest.h"
13
14#include "webrtc/call.h"
15#include "webrtc/system_wrappers/interface/clock.h"
16
17namespace webrtc {
18namespace test {
19
20DirectTransport::DirectTransport()
21    : lock_(CriticalSectionWrapper::CreateCriticalSection()),
22      packet_event_(EventWrapper::Create()),
23      thread_(ThreadWrapper::CreateThread(NetworkProcess, this)),
24      clock_(Clock::GetRealTimeClock()),
25      shutting_down_(false),
26      fake_network_(FakeNetworkPipe::Config()) {
27  unsigned int thread_id;
28  EXPECT_TRUE(thread_->Start(thread_id));
29}
30
31DirectTransport::DirectTransport(
32    const FakeNetworkPipe::Config& config)
33    : lock_(CriticalSectionWrapper::CreateCriticalSection()),
34      packet_event_(EventWrapper::Create()),
35      thread_(ThreadWrapper::CreateThread(NetworkProcess, this)),
36      clock_(Clock::GetRealTimeClock()),
37      shutting_down_(false),
38      fake_network_(config) {
39  unsigned int thread_id;
40  EXPECT_TRUE(thread_->Start(thread_id));
41}
42
43DirectTransport::~DirectTransport() { StopSending(); }
44
45void DirectTransport::SetConfig(const FakeNetworkPipe::Config& config) {
46  fake_network_.SetConfig(config);
47}
48
49void DirectTransport::StopSending() {
50  {
51    CriticalSectionScoped crit_(lock_.get());
52    shutting_down_ = true;
53  }
54
55  packet_event_->Set();
56  EXPECT_TRUE(thread_->Stop());
57}
58
59void DirectTransport::SetReceiver(PacketReceiver* receiver) {
60  fake_network_.SetReceiver(receiver);
61}
62
63bool DirectTransport::SendRtp(const uint8_t* data, size_t length) {
64  fake_network_.SendPacket(data, length);
65  packet_event_->Set();
66  return true;
67}
68
69bool DirectTransport::SendRtcp(const uint8_t* data, size_t length) {
70  fake_network_.SendPacket(data, length);
71  packet_event_->Set();
72  return true;
73}
74
75bool DirectTransport::NetworkProcess(void* transport) {
76  return static_cast<DirectTransport*>(transport)->SendPackets();
77}
78
79bool DirectTransport::SendPackets() {
80  fake_network_.Process();
81  int wait_time_ms = fake_network_.TimeUntilNextProcess();
82  if (wait_time_ms > 0) {
83    switch (packet_event_->Wait(wait_time_ms)) {
84      case kEventSignaled:
85        packet_event_->Reset();
86        break;
87      case kEventTimeout:
88        break;
89      case kEventError:
90        // TODO(pbos): Log a warning here?
91        return true;
92    }
93  }
94  CriticalSectionScoped crit(lock_.get());
95  return shutting_down_ ? false : true;
96}
97}  // namespace test
98}  // namespace webrtc
99