• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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