blob: b0c10c07ff20a1ef93666239a0b176d444c99486 [file] [log] [blame]
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +00001/*
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
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000011#ifndef WEBRTC_TEST_FAKE_NETWORK_PIPE_H_
12#define WEBRTC_TEST_FAKE_NETWORK_PIPE_H_
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000013
kwibergbfefb032016-05-01 14:53:46 -070014#include <memory>
philipela2c55232016-01-26 08:41:53 -080015#include <set>
16#include <string.h>
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000017#include <queue>
18
henrike@webrtc.org88fbb2d2014-05-21 21:18:46 +000019#include "webrtc/base/constructormagic.h"
Peter Boströmf2f82832015-05-01 13:00:41 +020020#include "webrtc/base/criticalsection.h"
philipela2c55232016-01-26 08:41:53 -080021#include "webrtc/base/random.h"
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000022#include "webrtc/typedefs.h"
23
24namespace webrtc {
25
Peter Boströmd3c94472015-12-09 11:20:58 +010026class Clock;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000027class CriticalSectionWrapper;
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000028class PacketReceiver;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000029
philipela2c55232016-01-26 08:41:53 -080030class NetworkPacket {
31 public:
32 NetworkPacket(const uint8_t* data,
33 size_t length,
34 int64_t send_time,
35 int64_t arrival_time)
36 : data_(new uint8_t[length]),
37 data_length_(length),
38 send_time_(send_time),
39 arrival_time_(arrival_time) {
40 memcpy(data_.get(), data, length);
41 }
42
43 uint8_t* data() const { return data_.get(); }
44 size_t data_length() const { return data_length_; }
45 int64_t send_time() const { return send_time_; }
46 int64_t arrival_time() const { return arrival_time_; }
47 void IncrementArrivalTime(int64_t extra_delay) {
48 arrival_time_ += extra_delay;
49 }
50
51 private:
52 // The packet data.
kwibergbfefb032016-05-01 14:53:46 -070053 std::unique_ptr<uint8_t[]> data_;
philipela2c55232016-01-26 08:41:53 -080054 // Length of data_.
55 size_t data_length_;
56 // The time the packet was sent out on the network.
57 const int64_t send_time_;
58 // The time the packet should arrive at the receiver.
59 int64_t arrival_time_;
60};
61
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000062// Class faking a network link. This is a simple and naive solution just faking
63// capacity and adding an extra transport delay in addition to the capacity
64// introduced delay.
65
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000066class FakeNetworkPipe {
67 public:
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000068 struct Config {
Peter Boströmd3c94472015-12-09 11:20:58 +010069 Config() {}
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000070 // Queue length in number of packets.
Peter Boströmd3c94472015-12-09 11:20:58 +010071 size_t queue_length_packets = 0;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +000072 // Delay in addition to capacity induced delay.
Peter Boströmd3c94472015-12-09 11:20:58 +010073 int queue_delay_ms = 0;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +000074 // Standard deviation of the extra delay.
Peter Boströmd3c94472015-12-09 11:20:58 +010075 int delay_standard_deviation_ms = 0;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +000076 // Link capacity in kbps.
Peter Boströmd3c94472015-12-09 11:20:58 +010077 int link_capacity_kbps = 0;
stefan@webrtc.orgbfe6e082014-07-31 12:30:18 +000078 // Random packet loss.
Peter Boströmd3c94472015-12-09 11:20:58 +010079 int loss_percent = 0;
philipela2c55232016-01-26 08:41:53 -080080 // If packets are allowed to be reordered.
81 bool allow_reordering = false;
philipel536378b2016-05-31 03:20:23 -070082 // The average length of a burst of lost packets.
83 int avg_burst_loss_length = -1;
mflodman@webrtc.org7acb65a2012-12-13 15:53:11 +000084 };
85
Peter Boströmd3c94472015-12-09 11:20:58 +010086 FakeNetworkPipe(Clock* clock, const FakeNetworkPipe::Config& config);
philipela2c55232016-01-26 08:41:53 -080087 FakeNetworkPipe(Clock* clock,
88 const FakeNetworkPipe::Config& config,
89 uint64_t seed);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000090 ~FakeNetworkPipe();
91
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000092 // Must not be called in parallel with SendPacket or Process.
93 void SetReceiver(PacketReceiver* receiver);
94
henrik.lundin@webrtc.orgc0e9aeb2014-02-26 13:34:52 +000095 // Sets a new configuration. This won't affect packets already in the pipe.
96 void SetConfig(const FakeNetworkPipe::Config& config);
97
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +000098 // Sends a new packet to the link.
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +000099 void SendPacket(const uint8_t* packet, size_t packet_length);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000100
101 // Processes the network queues and trigger PacketReceiver::IncomingPacket for
102 // packets ready to be delivered.
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000103 void Process();
pkasting@chromium.org0b1534c2014-12-15 22:09:40 +0000104 int64_t TimeUntilNextProcess() const;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000105
106 // Get statistics.
107 float PercentageLoss();
108 int AverageDelay();
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000109 size_t dropped_packets() { return dropped_packets_; }
110 size_t sent_packets() { return sent_packets_; }
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000111
112 private:
Peter Boströmd3c94472015-12-09 11:20:58 +0100113 Clock* const clock_;
pbos5ad935c2016-01-25 03:52:44 -0800114 rtc::CriticalSection lock_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000115 PacketReceiver* packet_receiver_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000116 std::queue<NetworkPacket*> capacity_link_;
philipela2c55232016-01-26 08:41:53 -0800117 Random random_;
118
119 // Since we need to access both the packet with the earliest and latest
120 // arrival time we need to use a multiset to keep all packets sorted,
121 // hence, we cannot use a priority queue.
122 struct PacketArrivalTimeComparator {
123 bool operator()(const NetworkPacket* p1, const NetworkPacket* p2) {
124 return p1->arrival_time() < p2->arrival_time();
125 }
126 };
127 std::multiset<NetworkPacket*, PacketArrivalTimeComparator> delay_link_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000128
129 // Link configuration.
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000130 Config config_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000131
132 // Statistics.
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000133 size_t dropped_packets_;
134 size_t sent_packets_;
Stefan Holmerff2a6352016-01-14 10:00:21 +0100135 int64_t total_packet_delay_;
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000136
philipel536378b2016-05-31 03:20:23 -0700137 // Are we currently dropping a burst of packets?
138 bool bursting_;
139
140 // The probability to drop the packet if we are currently dropping a
141 // burst of packet
142 double prob_loss_bursting_;
143
144 // The probability to drop a burst of packets.
145 double prob_start_bursting_;
146
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000147 int64_t next_process_time_;
148
henrikg3c089d72015-09-16 05:37:44 -0700149 RTC_DISALLOW_COPY_AND_ASSIGN(FakeNetworkPipe);
mflodman@webrtc.orgeaf7cf22012-12-11 11:47:22 +0000150};
151
152} // namespace webrtc
153
stefan@webrtc.orgfaada6e2013-12-18 20:28:25 +0000154#endif // WEBRTC_TEST_FAKE_NETWORK_PIPE_H_