1 /*
2 * Copyright 2017 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 #include "rtc_tools/network_tester/packet_sender.h"
12
13 #include <algorithm>
14 #include <memory>
15 #include <string>
16 #include <utility>
17
18 #include "absl/types/optional.h"
19 #include "api/task_queue/default_task_queue_factory.h"
20 #include "api/task_queue/queued_task.h"
21 #include "api/task_queue/task_queue_base.h"
22 #include "rtc_base/time_utils.h"
23 #include "rtc_tools/network_tester/config_reader.h"
24 #include "rtc_tools/network_tester/test_controller.h"
25
26 namespace webrtc {
27
28 namespace {
29
30 class SendPacketTask : public QueuedTask {
31 public:
SendPacketTask(PacketSender * packet_sender)32 explicit SendPacketTask(PacketSender* packet_sender)
33 : target_time_ms_(rtc::TimeMillis()), packet_sender_(packet_sender) {}
34
35 private:
Run()36 bool Run() override {
37 if (packet_sender_->IsSending()) {
38 packet_sender_->SendPacket();
39 target_time_ms_ += packet_sender_->GetSendIntervalMs();
40 int64_t delay_ms = std::max(static_cast<int64_t>(0),
41 target_time_ms_ - rtc::TimeMillis());
42 TaskQueueBase::Current()->PostDelayedTask(
43 std::unique_ptr<QueuedTask>(this), delay_ms);
44 return false;
45 } else {
46 return true;
47 }
48 }
49 int64_t target_time_ms_;
50 PacketSender* const packet_sender_;
51 };
52
53 class UpdateTestSettingTask : public QueuedTask {
54 public:
UpdateTestSettingTask(PacketSender * packet_sender,std::unique_ptr<ConfigReader> config_reader)55 UpdateTestSettingTask(PacketSender* packet_sender,
56 std::unique_ptr<ConfigReader> config_reader)
57 : packet_sender_(packet_sender),
58 config_reader_(std::move(config_reader)) {}
59
60 private:
Run()61 bool Run() override {
62 auto config = config_reader_->GetNextConfig();
63 if (config) {
64 packet_sender_->UpdateTestSetting((*config).packet_size,
65 (*config).packet_send_interval_ms);
66 TaskQueueBase::Current()->PostDelayedTask(
67 std::unique_ptr<QueuedTask>(this), (*config).execution_time_ms);
68 return false;
69 } else {
70 packet_sender_->StopSending();
71 return true;
72 }
73 }
74 PacketSender* const packet_sender_;
75 const std::unique_ptr<ConfigReader> config_reader_;
76 };
77
78 } // namespace
79
PacketSender(TestController * test_controller,const std::string & config_file_path)80 PacketSender::PacketSender(TestController* test_controller,
81 const std::string& config_file_path)
82 : packet_size_(0),
83 send_interval_ms_(0),
84 sequence_number_(0),
85 sending_(false),
86 config_file_path_(config_file_path),
87 test_controller_(test_controller),
88 task_queue_factory_(CreateDefaultTaskQueueFactory()),
89 worker_queue_(task_queue_factory_->CreateTaskQueue(
90 "Packet Sender",
91 TaskQueueFactory::Priority::HIGH)) {}
92
93 PacketSender::~PacketSender() = default;
94
StartSending()95 void PacketSender::StartSending() {
96 worker_queue_checker_.Detach();
97 worker_queue_.PostTask([this]() {
98 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
99 sending_ = true;
100 });
101 worker_queue_.PostTask(std::make_unique<UpdateTestSettingTask>(
102 this, std::make_unique<ConfigReader>(config_file_path_)));
103 worker_queue_.PostTask(std::make_unique<SendPacketTask>(this));
104 }
105
StopSending()106 void PacketSender::StopSending() {
107 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
108 sending_ = false;
109 test_controller_->OnTestDone();
110 }
111
IsSending() const112 bool PacketSender::IsSending() const {
113 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
114 return sending_;
115 }
116
SendPacket()117 void PacketSender::SendPacket() {
118 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
119 NetworkTesterPacket packet;
120 packet.set_type(NetworkTesterPacket::TEST_DATA);
121 packet.set_sequence_number(sequence_number_++);
122 packet.set_send_timestamp(rtc::TimeMicros());
123 test_controller_->SendData(packet, packet_size_);
124 }
125
GetSendIntervalMs() const126 int64_t PacketSender::GetSendIntervalMs() const {
127 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
128 return send_interval_ms_;
129 }
130
UpdateTestSetting(size_t packet_size,int64_t send_interval_ms)131 void PacketSender::UpdateTestSetting(size_t packet_size,
132 int64_t send_interval_ms) {
133 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
134 send_interval_ms_ = send_interval_ms;
135 packet_size_ = packet_size;
136 }
137
138 } // namespace webrtc
139