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#ifndef WEBRTC_TEST_FAKE_NETWORK_PIPE_H_
12#define WEBRTC_TEST_FAKE_NETWORK_PIPE_H_
13
14#include <queue>
15
16#include "webrtc/base/constructormagic.h"
17#include "webrtc/base/criticalsection.h"
18#include "webrtc/base/scoped_ptr.h"
19#include "webrtc/typedefs.h"
20
21namespace webrtc {
22
23class Clock;
24class CriticalSectionWrapper;
25class NetworkPacket;
26class PacketReceiver;
27
28// Class faking a network link. This is a simple and naive solution just faking
29// capacity and adding an extra transport delay in addition to the capacity
30// introduced delay.
31
32// TODO(mflodman) Add random and bursty packet loss.
33class FakeNetworkPipe {
34 public:
35  struct Config {
36    Config() {}
37    // Queue length in number of packets.
38    size_t queue_length_packets = 0;
39    // Delay in addition to capacity induced delay.
40    int queue_delay_ms = 0;
41    // Standard deviation of the extra delay.
42    int delay_standard_deviation_ms = 0;
43    // Link capacity in kbps.
44    int link_capacity_kbps = 0;
45    // Random packet loss.
46    int loss_percent = 0;
47  };
48
49  FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config);
50  ~FakeNetworkPipe();
51
52  // Must not be called in parallel with SendPacket or Process.
53  void SetReceiver(PacketReceiver* receiver);
54
55  // Sets a new configuration. This won't affect packets already in the pipe.
56  void SetConfig(const FakeNetworkPipe::Config& config);
57
58  // Sends a new packet to the link.
59  void SendPacket(const uint8_t* packet, size_t packet_length);
60
61  // Processes the network queues and trigger PacketReceiver::IncomingPacket for
62  // packets ready to be delivered.
63  void Process();
64  int64_t TimeUntilNextProcess() const;
65
66  // Get statistics.
67  float PercentageLoss();
68  int AverageDelay();
69  size_t dropped_packets() { return dropped_packets_; }
70  size_t sent_packets() { return sent_packets_; }
71
72 private:
73  Clock* const clock_;
74  mutable rtc::CriticalSection lock_;
75  PacketReceiver* packet_receiver_;
76  std::queue<NetworkPacket*> capacity_link_;
77  std::queue<NetworkPacket*> delay_link_;
78
79  // Link configuration.
80  Config config_;
81
82  // Statistics.
83  size_t dropped_packets_;
84  size_t sent_packets_;
85  int64_t total_packet_delay_;
86
87  int64_t next_process_time_;
88
89  RTC_DISALLOW_COPY_AND_ASSIGN(FakeNetworkPipe);
90};
91
92}  // namespace webrtc
93
94#endif  // WEBRTC_TEST_FAKE_NETWORK_PIPE_H_
95