xref: /aosp_15_r20/external/webrtc/call/simulated_network.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker  *  Copyright 2018 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker  *
4*d9f75844SAndroid Build Coastguard Worker  *  Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker  *  that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker  *  tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker  *  in the file PATENTS.  All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker  *  be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker  */
10*d9f75844SAndroid Build Coastguard Worker #ifndef CALL_SIMULATED_NETWORK_H_
11*d9f75844SAndroid Build Coastguard Worker #define CALL_SIMULATED_NETWORK_H_
12*d9f75844SAndroid Build Coastguard Worker 
13*d9f75844SAndroid Build Coastguard Worker #include <stdint.h>
14*d9f75844SAndroid Build Coastguard Worker 
15*d9f75844SAndroid Build Coastguard Worker #include <deque>
16*d9f75844SAndroid Build Coastguard Worker #include <queue>
17*d9f75844SAndroid Build Coastguard Worker #include <vector>
18*d9f75844SAndroid Build Coastguard Worker 
19*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
20*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h"
21*d9f75844SAndroid Build Coastguard Worker #include "api/test/simulated_network.h"
22*d9f75844SAndroid Build Coastguard Worker #include "api/units/data_size.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/units/timestamp.h"
24*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/race_checker.h"
25*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/random.h"
26*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h"
27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread_annotations.h"
28*d9f75844SAndroid Build Coastguard Worker 
29*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
30*d9f75844SAndroid Build Coastguard Worker 
31*d9f75844SAndroid Build Coastguard Worker // Class simulating a network link.
32*d9f75844SAndroid Build Coastguard Worker //
33*d9f75844SAndroid Build Coastguard Worker // This is a basic implementation of NetworkBehaviorInterface that supports:
34*d9f75844SAndroid Build Coastguard Worker // - Packet loss
35*d9f75844SAndroid Build Coastguard Worker // - Capacity delay
36*d9f75844SAndroid Build Coastguard Worker // - Extra delay with or without packets reorder
37*d9f75844SAndroid Build Coastguard Worker // - Packet overhead
38*d9f75844SAndroid Build Coastguard Worker // - Queue max capacity
39*d9f75844SAndroid Build Coastguard Worker class SimulatedNetwork : public SimulatedNetworkInterface {
40*d9f75844SAndroid Build Coastguard Worker  public:
41*d9f75844SAndroid Build Coastguard Worker   using Config = BuiltInNetworkBehaviorConfig;
42*d9f75844SAndroid Build Coastguard Worker   explicit SimulatedNetwork(Config config, uint64_t random_seed = 1);
43*d9f75844SAndroid Build Coastguard Worker   ~SimulatedNetwork() override;
44*d9f75844SAndroid Build Coastguard Worker 
45*d9f75844SAndroid Build Coastguard Worker   // Sets a new configuration. This will affect packets that will be sent with
46*d9f75844SAndroid Build Coastguard Worker   // EnqueuePacket but also packets in the network that have not left the
47*d9f75844SAndroid Build Coastguard Worker   // network emulation. Packets that are ready to be retrieved by
48*d9f75844SAndroid Build Coastguard Worker   // DequeueDeliverablePackets are not affected by the new configuration.
49*d9f75844SAndroid Build Coastguard Worker   // TODO(bugs.webrtc.org/14525): Fix SetConfig and make it apply only to the
50*d9f75844SAndroid Build Coastguard Worker   // part of the packet that is currently being sent (instead of applying to
51*d9f75844SAndroid Build Coastguard Worker   // all of it).
52*d9f75844SAndroid Build Coastguard Worker   void SetConfig(const Config& config) override;
53*d9f75844SAndroid Build Coastguard Worker   void UpdateConfig(std::function<void(BuiltInNetworkBehaviorConfig*)>
54*d9f75844SAndroid Build Coastguard Worker                         config_modifier) override;
55*d9f75844SAndroid Build Coastguard Worker   void PauseTransmissionUntil(int64_t until_us) override;
56*d9f75844SAndroid Build Coastguard Worker 
57*d9f75844SAndroid Build Coastguard Worker   // NetworkBehaviorInterface
58*d9f75844SAndroid Build Coastguard Worker   bool EnqueuePacket(PacketInFlightInfo packet) override;
59*d9f75844SAndroid Build Coastguard Worker   std::vector<PacketDeliveryInfo> DequeueDeliverablePackets(
60*d9f75844SAndroid Build Coastguard Worker       int64_t receive_time_us) override;
61*d9f75844SAndroid Build Coastguard Worker 
62*d9f75844SAndroid Build Coastguard Worker   absl::optional<int64_t> NextDeliveryTimeUs() const override;
63*d9f75844SAndroid Build Coastguard Worker 
64*d9f75844SAndroid Build Coastguard Worker  private:
65*d9f75844SAndroid Build Coastguard Worker   struct PacketInfo {
66*d9f75844SAndroid Build Coastguard Worker     PacketInFlightInfo packet;
67*d9f75844SAndroid Build Coastguard Worker     // Time when the packet has left (or will leave) the network.
68*d9f75844SAndroid Build Coastguard Worker     int64_t arrival_time_us;
69*d9f75844SAndroid Build Coastguard Worker   };
70*d9f75844SAndroid Build Coastguard Worker   // Contains current configuration state.
71*d9f75844SAndroid Build Coastguard Worker   struct ConfigState {
72*d9f75844SAndroid Build Coastguard Worker     // Static link configuration.
73*d9f75844SAndroid Build Coastguard Worker     Config config;
74*d9f75844SAndroid Build Coastguard Worker     // The probability to drop the packet if we are currently dropping a
75*d9f75844SAndroid Build Coastguard Worker     // burst of packet
76*d9f75844SAndroid Build Coastguard Worker     double prob_loss_bursting;
77*d9f75844SAndroid Build Coastguard Worker     // The probability to drop a burst of packets.
78*d9f75844SAndroid Build Coastguard Worker     double prob_start_bursting;
79*d9f75844SAndroid Build Coastguard Worker     // Used for temporary delay spikes.
80*d9f75844SAndroid Build Coastguard Worker     int64_t pause_transmission_until_us = 0;
81*d9f75844SAndroid Build Coastguard Worker   };
82*d9f75844SAndroid Build Coastguard Worker 
83*d9f75844SAndroid Build Coastguard Worker   // Moves packets from capacity- to delay link.
84*d9f75844SAndroid Build Coastguard Worker   void UpdateCapacityQueue(ConfigState state, int64_t time_now_us)
85*d9f75844SAndroid Build Coastguard Worker       RTC_RUN_ON(&process_checker_);
86*d9f75844SAndroid Build Coastguard Worker   ConfigState GetConfigState() const;
87*d9f75844SAndroid Build Coastguard Worker 
88*d9f75844SAndroid Build Coastguard Worker   mutable Mutex config_lock_;
89*d9f75844SAndroid Build Coastguard Worker 
90*d9f75844SAndroid Build Coastguard Worker   // Guards the data structures involved in delay and loss processing, such as
91*d9f75844SAndroid Build Coastguard Worker   // the packet queues.
92*d9f75844SAndroid Build Coastguard Worker   rtc::RaceChecker process_checker_;
93*d9f75844SAndroid Build Coastguard Worker   // Models the capacity of the network by rejecting packets if the queue is
94*d9f75844SAndroid Build Coastguard Worker   // full and keeping them in the queue until they are ready to exit (according
95*d9f75844SAndroid Build Coastguard Worker   // to the link capacity, which cannot be violated, e.g. a 1 kbps link will
96*d9f75844SAndroid Build Coastguard Worker   // only be able to deliver 1000 bits per second).
97*d9f75844SAndroid Build Coastguard Worker   //
98*d9f75844SAndroid Build Coastguard Worker   // Invariant:
99*d9f75844SAndroid Build Coastguard Worker   // The head of the `capacity_link_` has arrival_time_us correctly set to the
100*d9f75844SAndroid Build Coastguard Worker   // time when the packet is supposed to be delivered (without accounting
101*d9f75844SAndroid Build Coastguard Worker   // potential packet loss or potential extra delay and without accounting for a
102*d9f75844SAndroid Build Coastguard Worker   // new configuration of the network, which requires a re-computation of the
103*d9f75844SAndroid Build Coastguard Worker   // arrival_time_us).
104*d9f75844SAndroid Build Coastguard Worker   std::queue<PacketInfo> capacity_link_ RTC_GUARDED_BY(process_checker_);
105*d9f75844SAndroid Build Coastguard Worker   // Models the extra delay of the network (see `queue_delay_ms`
106*d9f75844SAndroid Build Coastguard Worker   // and `delay_standard_deviation_ms` in BuiltInNetworkBehaviorConfig), packets
107*d9f75844SAndroid Build Coastguard Worker   // in the `delay_link_` have technically already left the network and don't
108*d9f75844SAndroid Build Coastguard Worker   // use its capacity but they are not delivered yet.
109*d9f75844SAndroid Build Coastguard Worker   std::deque<PacketInfo> delay_link_ RTC_GUARDED_BY(process_checker_);
110*d9f75844SAndroid Build Coastguard Worker   // Represents the next moment in time when the network is supposed to deliver
111*d9f75844SAndroid Build Coastguard Worker   // packets to the client (either by pulling them from `delay_link_` or
112*d9f75844SAndroid Build Coastguard Worker   // `capacity_link_` or both).
113*d9f75844SAndroid Build Coastguard Worker   absl::optional<int64_t> next_process_time_us_
114*d9f75844SAndroid Build Coastguard Worker       RTC_GUARDED_BY(process_checker_);
115*d9f75844SAndroid Build Coastguard Worker 
116*d9f75844SAndroid Build Coastguard Worker   ConfigState config_state_ RTC_GUARDED_BY(config_lock_);
117*d9f75844SAndroid Build Coastguard Worker 
118*d9f75844SAndroid Build Coastguard Worker   Random random_ RTC_GUARDED_BY(process_checker_);
119*d9f75844SAndroid Build Coastguard Worker   // Are we currently dropping a burst of packets?
120*d9f75844SAndroid Build Coastguard Worker   bool bursting_;
121*d9f75844SAndroid Build Coastguard Worker 
122*d9f75844SAndroid Build Coastguard Worker   // The send time of the last enqueued packet, this is only used to check that
123*d9f75844SAndroid Build Coastguard Worker   // the send time of enqueued packets is monotonically increasing.
124*d9f75844SAndroid Build Coastguard Worker   int64_t last_enqueue_time_us_;
125*d9f75844SAndroid Build Coastguard Worker 
126*d9f75844SAndroid Build Coastguard Worker   // The last time a packet left the capacity_link_ (used to enforce
127*d9f75844SAndroid Build Coastguard Worker   // the capacity of the link and avoid packets starts to get sent before
128*d9f75844SAndroid Build Coastguard Worker   // the link it free).
129*d9f75844SAndroid Build Coastguard Worker   int64_t last_capacity_link_exit_time_;
130*d9f75844SAndroid Build Coastguard Worker };
131*d9f75844SAndroid Build Coastguard Worker 
132*d9f75844SAndroid Build Coastguard Worker }  // namespace webrtc
133*d9f75844SAndroid Build Coastguard Worker 
134*d9f75844SAndroid Build Coastguard Worker #endif  // CALL_SIMULATED_NETWORK_H_
135