• 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/test_controller.h"
12 
13 #include <limits>
14 
15 #include "absl/types/optional.h"
16 #include "rtc_base/checks.h"
17 #include "rtc_base/ip_address.h"
18 #include "rtc_base/thread.h"
19 
20 namespace webrtc {
21 
TestController(int min_port,int max_port,const std::string & config_file_path,const std::string & log_file_path)22 TestController::TestController(int min_port,
23                                int max_port,
24                                const std::string& config_file_path,
25                                const std::string& log_file_path)
26     : socket_factory_(rtc::ThreadManager::Instance()->WrapCurrentThread()),
27       config_file_path_(config_file_path),
28       packet_logger_(log_file_path),
29       local_test_done_(false),
30       remote_test_done_(false) {
31   RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
32   packet_sender_checker_.Detach();
33   send_data_.fill(42);
34   udp_socket_ =
35       std::unique_ptr<rtc::AsyncPacketSocket>(socket_factory_.CreateUdpSocket(
36           rtc::SocketAddress(rtc::GetAnyIP(AF_INET), 0), min_port, max_port));
37   udp_socket_->SignalReadPacket.connect(this, &TestController::OnReadPacket);
38 }
39 
SendConnectTo(const std::string & hostname,int port)40 void TestController::SendConnectTo(const std::string& hostname, int port) {
41   RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
42   remote_address_ = rtc::SocketAddress(hostname, port);
43   NetworkTesterPacket packet;
44   packet.set_type(NetworkTesterPacket::HAND_SHAKING);
45   SendData(packet, absl::nullopt);
46   MutexLock scoped_lock(&local_test_done_lock_);
47   local_test_done_ = false;
48   remote_test_done_ = false;
49 }
50 
Run()51 void TestController::Run() {
52   RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
53   rtc::Thread::Current()->ProcessMessages(0);
54 }
55 
SendData(const NetworkTesterPacket & packet,absl::optional<size_t> data_size)56 void TestController::SendData(const NetworkTesterPacket& packet,
57                               absl::optional<size_t> data_size) {
58   // Can be call from packet_sender or from test_controller thread.
59   size_t packet_size = packet.ByteSizeLong();
60   send_data_[0] = packet_size;
61   packet_size++;
62   packet.SerializeToArray(&send_data_[1], std::numeric_limits<char>::max());
63   if (data_size && *data_size > packet_size)
64     packet_size = *data_size;
65   udp_socket_->SendTo((const void*)send_data_.data(), packet_size,
66                       remote_address_, rtc::PacketOptions());
67 }
68 
OnTestDone()69 void TestController::OnTestDone() {
70   RTC_DCHECK_RUN_ON(&packet_sender_checker_);
71   NetworkTesterPacket packet;
72   packet.set_type(NetworkTesterPacket::TEST_DONE);
73   SendData(packet, absl::nullopt);
74   MutexLock scoped_lock(&local_test_done_lock_);
75   local_test_done_ = true;
76 }
77 
IsTestDone()78 bool TestController::IsTestDone() {
79   RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
80   MutexLock scoped_lock(&local_test_done_lock_);
81   return local_test_done_ && remote_test_done_;
82 }
83 
OnReadPacket(rtc::AsyncPacketSocket * socket,const char * data,size_t len,const rtc::SocketAddress & remote_addr,const int64_t & packet_time_us)84 void TestController::OnReadPacket(rtc::AsyncPacketSocket* socket,
85                                   const char* data,
86                                   size_t len,
87                                   const rtc::SocketAddress& remote_addr,
88                                   const int64_t& packet_time_us) {
89   RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
90   size_t packet_size = data[0];
91   std::string receive_data(&data[1], packet_size);
92   NetworkTesterPacket packet;
93   packet.ParseFromString(receive_data);
94   RTC_CHECK(packet.has_type());
95   switch (packet.type()) {
96     case NetworkTesterPacket::HAND_SHAKING: {
97       NetworkTesterPacket packet;
98       packet.set_type(NetworkTesterPacket::TEST_START);
99       remote_address_ = remote_addr;
100       SendData(packet, absl::nullopt);
101       packet_sender_.reset(new PacketSender(this, config_file_path_));
102       packet_sender_->StartSending();
103       MutexLock scoped_lock(&local_test_done_lock_);
104       local_test_done_ = false;
105       remote_test_done_ = false;
106       break;
107     }
108     case NetworkTesterPacket::TEST_START: {
109       packet_sender_.reset(new PacketSender(this, config_file_path_));
110       packet_sender_->StartSending();
111       MutexLock scoped_lock(&local_test_done_lock_);
112       local_test_done_ = false;
113       remote_test_done_ = false;
114       break;
115     }
116     case NetworkTesterPacket::TEST_DATA: {
117       packet.set_arrival_timestamp(packet_time_us);
118       packet.set_packet_size(len);
119       packet_logger_.LogPacket(packet);
120       break;
121     }
122     case NetworkTesterPacket::TEST_DONE: {
123       remote_test_done_ = true;
124       break;
125     }
126     default: {
127       RTC_NOTREACHED();
128     }
129   }
130 }
131 
132 }  // namespace webrtc
133