Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / media / cast / test / utility / udp_proxy.h
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef MEDIA_CAST_TEST_UTILITY_UDP_PROXY_H_
6 #define MEDIA_CAST_TEST_UTILITY_UDP_PROXY_H_
7
8 #include <vector>
9
10 #include "base/basictypes.h"
11 #include "base/memory/linked_ptr.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/single_thread_task_runner.h"
16 #include "media/cast/net/cast_transport_config.h"
17 #include "net/base/ip_endpoint.h"
18 #include "third_party/mt19937ar/mt19937ar.h"
19
20 namespace net {
21 class NetLog;
22 };
23
24 namespace base {
25 class TickClock;
26 };
27
28 namespace media {
29 namespace cast {
30 namespace test {
31
32 class PacketPipe {
33  public:
34   PacketPipe();
35   virtual ~PacketPipe();
36   virtual void Send(scoped_ptr<Packet> packet) = 0;
37   // Allows injection of fake test runner for testing.
38   virtual void InitOnIOThread(
39       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
40       base::TickClock* clock);
41   virtual void AppendToPipe(scoped_ptr<PacketPipe> pipe);
42  protected:
43   scoped_ptr<PacketPipe> pipe_;
44   // Allows injection of fake task runner for testing.
45   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
46   base::TickClock* clock_;
47 };
48
49 // Implements a Interrupted Poisson Process for packet delivery.
50 // The process has 2 states: ON and OFF, the rate of switching between
51 // these two states are defined.
52 // When in ON state packets are sent according to a defined rate.
53 // When in OFF state packets are not sent.
54 // The rate above is the average rate of a poisson distribution.
55 class InterruptedPoissonProcess {
56  public:
57   InterruptedPoissonProcess(
58       const std::vector<double>& average_rates,
59       double coef_burstiness,
60       double coef_variance,
61       uint32 rand_seed);
62   ~InterruptedPoissonProcess();
63
64   scoped_ptr<PacketPipe> NewBuffer(size_t size);
65
66  private:
67   class InternalBuffer;
68
69   // |task_runner| is the executor of the IO thread.
70   // |clock| is the system clock.
71   void InitOnIOThread(
72       const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
73       base::TickClock* clock);
74
75   base::TimeDelta NextEvent(double rate);
76   double RandDouble();
77   void ComputeRates();
78   void UpdateRates();
79   void SwitchOff();
80   void SwitchOn();
81   void SendPacket();
82
83   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
84   base::TickClock* clock_;
85   const std::vector<double> average_rates_;
86   const double coef_burstiness_;
87   const double coef_variance_;
88   int rate_index_;
89
90   // The following rates are per milliseconds.
91   double send_rate_;
92   double switch_off_rate_;
93   double switch_on_rate_;
94   bool on_state_;
95
96   std::vector<base::WeakPtr<InternalBuffer> > send_buffers_;
97
98   // Fast pseudo random number generator.
99   MersenneTwister mt_rand_;
100
101   base::WeakPtrFactory<InterruptedPoissonProcess> weak_factory_;
102
103   DISALLOW_COPY_AND_ASSIGN(InterruptedPoissonProcess);
104 };
105
106 // A UDPProxy will set up a UDP socket and bind to |local_port|.
107 // Packets send to that port will be forwarded to |destination|.
108 // Packets send from |destination| to |local_port| will be returned
109 // to whoever sent a packet to |local_port| last. (Not counting packets
110 // from |destination|.) The UDPProxy will run a separate thread to
111 // do the forwarding of packets, and will keep doing so until destroyed.
112 // You can insert delays and packet drops by supplying a PacketPipe.
113 // The PacketPipes may also be NULL if you just want to forward packets.
114 class UDPProxy {
115  public:
116   virtual ~UDPProxy() {}
117   static scoped_ptr<UDPProxy> Create(const net::IPEndPoint& local_port,
118                                      const net::IPEndPoint& destination,
119                                      scoped_ptr<PacketPipe> to_dest_pipe,
120                                      scoped_ptr<PacketPipe> from_dest_pipe,
121                                      net::NetLog* net_log);
122 };
123
124 // The following functions create PacketPipes which can be linked
125 // together (with AppendToPipe) and passed into UdpProxy::Create below.
126
127 // This PacketPipe emulates a buffer of a given size. Limits our output
128 // from the buffer at a rate given by |bandwidth| (in megabits per second).
129 // Packets entering the buffer will be dropped if there is not enough
130 // room for them.
131 scoped_ptr<PacketPipe> NewBuffer(size_t buffer_size, double bandwidth);
132
133 // Randomly drops |drop_fraction|*100% of packets.
134 scoped_ptr<PacketPipe> NewRandomDrop(double drop_fraction);
135
136 // Delays each packet by |delay_seconds|.
137 scoped_ptr<PacketPipe> NewConstantDelay(double delay_seconds);
138
139 // Delays packets by a random amount between zero and |delay|.
140 // This PacketPipe can reorder packets.
141 scoped_ptr<PacketPipe> NewRandomUnsortedDelay(double delay);
142
143 // This PacketPipe inserts a random delay between each packet.
144 // This PacketPipe cannot re-order packets. The delay between each
145 // packet is asically |min_delay| + random( |random_delay| )
146 // However, every now and then a delay of |big_delay| will be
147 // inserted (roughly every |seconds_between_big_delay| seconds).
148 scoped_ptr<PacketPipe> NewRandomSortedDelay(double random_delay,
149                                             double big_delay,
150                                             double seconds_between_big_delay);
151
152 // This PacketPipe emulates network outages. It basically waits
153 // for 0-2*|average_work_time| seconds, then kills the network for
154 // 0-|2*average_outage_time| seconds. Then it starts over again.
155 scoped_ptr<PacketPipe> NewNetworkGlitchPipe(double average_work_time,
156                                             double average_outage_time);
157
158 // This method builds a stack of PacketPipes to emulate a reasonably
159 // good network. ~50mbit, ~3ms latency, no packet loss unless saturated.
160 scoped_ptr<PacketPipe> GoodNetwork();
161
162 // This method builds a stack of PacketPipes to emulate a reasonably
163 // good wifi network. ~20mbit, 1% packet loss, ~3ms latency.
164 scoped_ptr<PacketPipe> WifiNetwork();
165
166 // This method builds a stack of PacketPipes to emulate a
167 // bad wifi network. ~5mbit, 5% packet loss, ~7ms latency
168 // 40ms dropouts every ~2 seconds. Can reorder packets.
169 scoped_ptr<PacketPipe> BadNetwork();
170
171 // This method builds a stack of PacketPipes to emulate a crappy wifi network.
172 // ~2mbit, 20% packet loss, ~40ms latency and packets can get reordered.
173 // 300ms drouputs every ~2 seconds.
174 scoped_ptr<PacketPipe> EvilNetwork();
175
176 }  // namespace test
177 }  // namespace cast
178 }  // namespace media
179
180 #endif  // MEDIA_CAST_TEST_UTILITY_UDP_PROXY_H_