1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef SRC_VOICE_ENGINE_MAIN_TEST_AUTO_TEST_STANDARD_TEST_BASE_AFTER_INIT_H_
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define SRC_VOICE_ENGINE_MAIN_TEST_AUTO_TEST_STANDARD_TEST_BASE_AFTER_INIT_H_
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
147d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org#include <deque>
157d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org
16aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org#include "webrtc/common_types.h"
177d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
187d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h"
19471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/system_wrappers/interface/scoped_ptr.h"
207d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h"
21471ae72f18e7b23a96b245dbd508386fe139449cpbos@webrtc.org#include "webrtc/voice_engine/test/auto_test/fixtures/before_initialization_fixture.h"
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass TestErrorObserver;
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.orgclass LoopBackTransport : public webrtc::Transport {
26aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org public:
27aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org  LoopBackTransport(webrtc::VoENetwork* voe_network)
287d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      : crit_(webrtc::CriticalSectionWrapper::CreateCriticalSection()),
297d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        packet_event_(webrtc::EventWrapper::Create()),
307d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        thread_(webrtc::ThreadWrapper::CreateThread(NetworkProcess, this)),
317d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        voe_network_(voe_network) {
327d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    unsigned int id;
337d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    thread_->Start(id);
347d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  }
35aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org
366b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org  ~LoopBackTransport() { thread_->Stop(); }
376b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org
386b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org  virtual int SendPacket(int channel, const void* data, int len) {
397d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    StorePacket(Packet::Rtp, channel, data, len);
40aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org    return len;
41aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org  }
42aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org
436b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org  virtual int SendRTCPPacket(int channel, const void* data, int len) {
447d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    StorePacket(Packet::Rtcp, channel, data, len);
45aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org    return len;
46aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org  }
47aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org
48aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org private:
497d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  struct Packet {
506b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org    enum Type { Rtp, Rtcp, } type;
517d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org
527d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    Packet() : len(0) {}
537d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    Packet(Type type, int channel, const void* data, int len)
547d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        : type(type), channel(channel), len(len) {
557d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      assert(len <= 1500);
567d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      memcpy(this->data, data, static_cast<size_t>(len));
577d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    }
587d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org
597d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    int channel;
607d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    uint8_t data[1500];
617d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    int len;
627d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  };
637d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org
647d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  void StorePacket(Packet::Type type, int channel, const void* data, int len) {
656b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org    webrtc::CriticalSectionScoped lock(crit_.get());
667d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    packet_queue_.push_back(Packet(type, channel, data, len));
677d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    packet_event_->Set();
687d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  }
696b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org
707d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  static bool NetworkProcess(void* transport) {
717d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    return static_cast<LoopBackTransport*>(transport)->SendPackets();
727d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  }
737d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org
747d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  bool SendPackets() {
757d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    switch (packet_event_->Wait(10)) {
767d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      case webrtc::kEventSignaled:
777d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        packet_event_->Reset();
787d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        break;
797d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      case webrtc::kEventTimeout:
807d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        break;
817d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      case webrtc::kEventError:
827d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        // TODO(pbos): Log a warning here?
837d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        return true;
847d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    }
857d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org
867d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    while (true) {
877d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      Packet p;
887d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      {
897d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        webrtc::CriticalSectionScoped lock(crit_.get());
907d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        if (packet_queue_.empty())
917d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org          break;
927d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        p = packet_queue_.front();
937d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        packet_queue_.pop_front();
947d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      }
957d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org
967d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      switch (p.type) {
977d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        case Packet::Rtp:
98fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org          voe_network_->ReceivedRTPPacket(p.channel, p.data, p.len,
99fec6b6e5999edec8c90efae54357f1aae6a4c7ddsolenberg@webrtc.org                                          webrtc::PacketTime());
1007d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org          break;
1017d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org        case Packet::Rtcp:
1027d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org          voe_network_->ReceivedRTCPPacket(p.channel, p.data, p.len);
1037d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org          break;
1047d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org      }
1057d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    }
1067d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org    return true;
1077d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  }
1087d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org
1097d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  webrtc::scoped_ptr<webrtc::CriticalSectionWrapper> crit_;
1107d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  webrtc::scoped_ptr<webrtc::EventWrapper> packet_event_;
1117d82c9d751d07c3b11e05647919e94fb38bb1dacpbos@webrtc.org  webrtc::scoped_ptr<webrtc::ThreadWrapper> thread_;
1126b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org  std::deque<Packet> packet_queue_ GUARDED_BY(crit_.get());
1136b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org  webrtc::VoENetwork* const voe_network_;
114aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org};
115aa922de5772e1e2ea821517e01e5f5a2cf09a0e2pwestin@webrtc.org
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// This fixture initializes the voice engine in addition to the work
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// done by the before-initialization fixture. It also registers an error
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// observer which will fail tests on error callbacks. This fixture is
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// useful to tests that want to run before we have started any form of
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// streaming through the voice engine.
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass AfterInitializationFixture : public BeforeInitializationFixture {
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org public:
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  AfterInitializationFixture();
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  virtual ~AfterInitializationFixture();
1256b15b511b77aa214651fcd911871b22cce00660fpbos@webrtc.org
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org protected:
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  webrtc::scoped_ptr<TestErrorObserver> error_observer_;
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org};
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif  // SRC_VOICE_ENGINE_MAIN_TEST_AUTO_TEST_STANDARD_TEST_BASE_AFTER_INIT_H_
131