1 /*
2 * Copyright 2019 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 #include "test/network/feedback_generator.h"
11
12 #include "absl/memory/memory.h"
13 #include "api/transport/network_types.h"
14 #include "rtc_base/checks.h"
15
16 namespace webrtc {
17
FeedbackGeneratorImpl(FeedbackGeneratorImpl::Config config)18 FeedbackGeneratorImpl::FeedbackGeneratorImpl(
19 FeedbackGeneratorImpl::Config config)
20 : conf_(config),
21 net_(TimeMode::kSimulated, EmulatedNetworkStatsGatheringMode::kDefault),
22 send_link_{new SimulatedNetwork(conf_.send_link)},
23 ret_link_{new SimulatedNetwork(conf_.return_link)},
24 route_(this,
25 net_.CreateRoute(
26 {net_.CreateEmulatedNode(absl::WrapUnique(send_link_))}),
27 net_.CreateRoute(
28 {net_.CreateEmulatedNode(absl::WrapUnique(ret_link_))})) {}
29
Now()30 Timestamp FeedbackGeneratorImpl::Now() {
31 return net_.Now();
32 }
33
Sleep(TimeDelta duration)34 void FeedbackGeneratorImpl::Sleep(TimeDelta duration) {
35 net_.time_controller()->AdvanceTime(duration);
36 }
37
SendPacket(size_t size)38 void FeedbackGeneratorImpl::SendPacket(size_t size) {
39 SentPacket sent;
40 sent.send_time = Now();
41 sent.size = DataSize::Bytes(size);
42 sent.sequence_number = sequence_number_++;
43 sent_packets_.push(sent);
44 route_.SendRequest(size, sent);
45 }
46
PopFeedback()47 std::vector<TransportPacketsFeedback> FeedbackGeneratorImpl::PopFeedback() {
48 std::vector<TransportPacketsFeedback> ret;
49 ret.swap(feedback_);
50 return ret;
51 }
52
SetSendConfig(BuiltInNetworkBehaviorConfig config)53 void FeedbackGeneratorImpl::SetSendConfig(BuiltInNetworkBehaviorConfig config) {
54 conf_.send_link = config;
55 send_link_->SetConfig(conf_.send_link);
56 }
57
SetReturnConfig(BuiltInNetworkBehaviorConfig config)58 void FeedbackGeneratorImpl::SetReturnConfig(
59 BuiltInNetworkBehaviorConfig config) {
60 conf_.return_link = config;
61 ret_link_->SetConfig(conf_.return_link);
62 }
63
SetSendLinkCapacity(DataRate capacity)64 void FeedbackGeneratorImpl::SetSendLinkCapacity(DataRate capacity) {
65 conf_.send_link.link_capacity_kbps = capacity.kbps<int>();
66 send_link_->SetConfig(conf_.send_link);
67 }
68
OnRequest(SentPacket packet,Timestamp arrival_time)69 void FeedbackGeneratorImpl::OnRequest(SentPacket packet,
70 Timestamp arrival_time) {
71 PacketResult result;
72 result.sent_packet = packet;
73 result.receive_time = arrival_time;
74 received_packets_.push_back(result);
75 Timestamp first_recv = received_packets_.front().receive_time;
76 if (Now() - first_recv > conf_.feedback_interval) {
77 route_.SendResponse(conf_.feedback_packet_size.bytes<size_t>(),
78 std::move(received_packets_));
79 received_packets_ = {};
80 }
81 }
82
OnResponse(std::vector<PacketResult> packet_results,Timestamp arrival_time)83 void FeedbackGeneratorImpl::OnResponse(std::vector<PacketResult> packet_results,
84 Timestamp arrival_time) {
85 TransportPacketsFeedback feedback;
86 feedback.feedback_time = arrival_time;
87 std::vector<PacketResult>::const_iterator received_packet_iterator =
88 packet_results.begin();
89 while (received_packet_iterator != packet_results.end()) {
90 RTC_DCHECK(!sent_packets_.empty() &&
91 sent_packets_.front().sequence_number <=
92 received_packet_iterator->sent_packet.sequence_number)
93 << "reordering not implemented";
94 if (sent_packets_.front().sequence_number <
95 received_packet_iterator->sent_packet.sequence_number) {
96 // Packet lost.
97 PacketResult lost;
98 lost.sent_packet = sent_packets_.front();
99 feedback.packet_feedbacks.push_back(lost);
100 }
101 if (sent_packets_.front().sequence_number ==
102 received_packet_iterator->sent_packet.sequence_number) {
103 feedback.packet_feedbacks.push_back(*received_packet_iterator);
104 ++received_packet_iterator;
105 }
106 sent_packets_.pop();
107 }
108 feedback_.push_back(feedback);
109 }
110
111 } // namespace webrtc
112