blob: b2c6cd921c57d8de25152ba1134677df3c0aa092 [file] [log] [blame]
minyue939df962017-04-19 01:58:38 -07001/*
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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "rtc_tools/network_tester/packet_sender.h"
minyue939df962017-04-19 01:58:38 -070012
tschumimd4aebb02017-05-22 00:04:30 -070013#include <algorithm>
Yves Gerey3e707812018-11-28 16:47:49 +010014#include <memory>
minyue939df962017-04-19 01:58:38 -070015#include <string>
16#include <utility>
17
Yves Gerey3e707812018-11-28 16:47:49 +010018#include "absl/types/optional.h"
Danil Chapovalov3993b182019-03-27 19:42:15 +010019#include "api/task_queue/default_task_queue_factory.h"
Danil Chapovalov471783f2019-03-11 14:26:02 +010020#include "api/task_queue/queued_task.h"
Danil Chapovalovad895282019-03-11 10:28:05 +000021#include "api/task_queue/task_queue_base.h"
Steve Anton10542f22019-01-11 09:11:00 -080022#include "rtc_base/time_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020023#include "rtc_tools/network_tester/config_reader.h"
24#include "rtc_tools/network_tester/test_controller.h"
minyue939df962017-04-19 01:58:38 -070025
26namespace webrtc {
27
28namespace {
29
Danil Chapovalov471783f2019-03-11 14:26:02 +010030class SendPacketTask : public QueuedTask {
minyue939df962017-04-19 01:58:38 -070031 public:
32 explicit SendPacketTask(PacketSender* packet_sender)
tschumimd4aebb02017-05-22 00:04:30 -070033 : target_time_ms_(rtc::TimeMillis()), packet_sender_(packet_sender) {}
minyue939df962017-04-19 01:58:38 -070034
35 private:
36 bool Run() override {
37 if (packet_sender_->IsSending()) {
38 packet_sender_->SendPacket();
tschumimd4aebb02017-05-22 00:04:30 -070039 target_time_ms_ += packet_sender_->GetSendIntervalMs();
40 int64_t delay_ms = std::max(static_cast<int64_t>(0),
41 target_time_ms_ - rtc::TimeMillis());
Danil Chapovalovad895282019-03-11 10:28:05 +000042 TaskQueueBase::Current()->PostDelayedTask(
tschumimd4aebb02017-05-22 00:04:30 -070043 std::unique_ptr<QueuedTask>(this), delay_ms);
minyue939df962017-04-19 01:58:38 -070044 return false;
45 } else {
46 return true;
47 }
48 }
tschumimd4aebb02017-05-22 00:04:30 -070049 int64_t target_time_ms_;
minyue939df962017-04-19 01:58:38 -070050 PacketSender* const packet_sender_;
51};
52
Danil Chapovalov471783f2019-03-11 14:26:02 +010053class UpdateTestSettingTask : public QueuedTask {
minyue939df962017-04-19 01:58:38 -070054 public:
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:
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);
Danil Chapovalovad895282019-03-11 10:28:05 +000066 TaskQueueBase::Current()->PostDelayedTask(
minyue939df962017-04-19 01:58:38 -070067 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
80PacketSender::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),
Danil Chapovalov3993b182019-03-27 19:42:15 +010088 task_queue_factory_(CreateDefaultTaskQueueFactory()),
89 worker_queue_(task_queue_factory_->CreateTaskQueue(
90 "Packet Sender",
91 TaskQueueFactory::Priority::HIGH)) {}
minyue939df962017-04-19 01:58:38 -070092
93PacketSender::~PacketSender() = default;
94
95void PacketSender::StartSending() {
96 worker_queue_checker_.Detach();
97 worker_queue_.PostTask([this]() {
Sebastian Janssonb55015e2019-04-09 13:44:04 +020098 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
minyue939df962017-04-19 01:58:38 -070099 sending_ = true;
100 });
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200101 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));
minyue939df962017-04-19 01:58:38 -0700104}
105
106void PacketSender::StopSending() {
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200107 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
minyue939df962017-04-19 01:58:38 -0700108 sending_ = false;
109 test_controller_->OnTestDone();
110}
111
112bool PacketSender::IsSending() const {
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200113 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
minyue939df962017-04-19 01:58:38 -0700114 return sending_;
115}
116
117void PacketSender::SendPacket() {
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200118 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
minyue939df962017-04-19 01:58:38 -0700119 NetworkTesterPacket packet;
120 packet.set_type(NetworkTesterPacket::TEST_DATA);
121 packet.set_sequence_number(sequence_number_++);
122 packet.set_send_timestamp(rtc::TimeMicros());
Oskar Sundbom59dd4822017-11-16 10:55:27 +0100123 test_controller_->SendData(packet, packet_size_);
minyue939df962017-04-19 01:58:38 -0700124}
125
126int64_t PacketSender::GetSendIntervalMs() const {
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200127 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
minyue939df962017-04-19 01:58:38 -0700128 return send_interval_ms_;
129}
130
131void PacketSender::UpdateTestSetting(size_t packet_size,
132 int64_t send_interval_ms) {
Sebastian Janssonb55015e2019-04-09 13:44:04 +0200133 RTC_DCHECK_RUN_ON(&worker_queue_checker_);
minyue939df962017-04-19 01:58:38 -0700134 send_interval_ms_ = send_interval_ms;
135 packet_size_ = packet_size;
136}
137
138} // namespace webrtc