diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 19:33:14 +0000 |
commit | 36d22d82aa202bb199967e9512281e9a53db42c9 (patch) | |
tree | 105e8c98ddea1c1e4784a60a5a6410fa416be2de /third_party/libwebrtc/rtc_tools/network_tester | |
parent | Initial commit. (diff) | |
download | firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.tar.xz firefox-esr-36d22d82aa202bb199967e9512281e9a53db42c9.zip |
Adding upstream version 115.7.0esr.upstream/115.7.0esrupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/libwebrtc/rtc_tools/network_tester')
31 files changed, 1390 insertions, 0 deletions
diff --git a/third_party/libwebrtc/rtc_tools/network_tester/BUILD.gn b/third_party/libwebrtc/rtc_tools/network_tester/BUILD.gn new file mode 100644 index 0000000000..e33a3c000f --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/BUILD.gn @@ -0,0 +1,184 @@ +# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +import("../../webrtc.gni") +if (rtc_enable_protobuf) { + import("//third_party/protobuf/proto_library.gni") +} + +if (rtc_enable_protobuf) { + proto_library("network_tester_config_proto") { + sources = [ "network_tester_config.proto" ] + proto_out_dir = "rtc_tools/network_tester" + } + + proto_library("network_tester_packet_proto") { + sources = [ "network_tester_packet.proto" ] + proto_out_dir = "rtc_tools/network_tester" + } + + rtc_library("network_tester") { + sources = [ + "config_reader.cc", + "config_reader.h", + "packet_logger.cc", + "packet_logger.h", + "packet_sender.cc", + "packet_sender.h", + "test_controller.cc", + "test_controller.h", + ] + + defines = [ "WEBRTC_NETWORK_TESTER_PROTO" ] + + deps = [ + ":network_tester_config_proto", + ":network_tester_packet_proto", + "../../api:sequence_checker", + "../../api/task_queue", + "../../api/task_queue:default_task_queue_factory", + "../../api/task_queue:pending_task_safety_flag", + "../../p2p:rtc_p2p", + "../../rtc_base:async_packet_socket", + "../../rtc_base:checks", + "../../rtc_base:ignore_wundef", + "../../rtc_base:ip_address", + "../../rtc_base:logging", + "../../rtc_base:macromagic", + "../../rtc_base:protobuf_utils", + "../../rtc_base:rtc_task_queue", + "../../rtc_base:socket_address", + "../../rtc_base:threading", + "../../rtc_base:timeutils", + "../../rtc_base/synchronization:mutex", + "../../rtc_base/system:no_unique_address", + "../../rtc_base/third_party/sigslot", + ] + absl_deps = [ + "//third_party/abseil-cpp/absl/functional:any_invocable", + "//third_party/abseil-cpp/absl/types:optional", + ] + } + + network_tester_unittests_resources = [ + "../../resources/network_tester/client_config.dat", + "../../resources/network_tester/server_config.dat", + ] + + if (is_ios) { + bundle_data("network_tester_unittests_bundle_data") { + testonly = true + sources = network_tester_unittests_resources + outputs = [ "{{bundle_resources_dir}}/{{source_file_part}}" ] + } + } + + rtc_library("network_tester_unittests") { + testonly = true + + sources = [ "network_tester_unittest.cc" ] + + deps = [ + ":network_tester", + "../../rtc_base:gunit_helpers", + "../../rtc_base:threading", + "../../test:fileutils", + "../../test:test_support", + "//testing/gtest", + ] + + if (is_ios) { + deps += [ ":network_tester_unittests_bundle_data" ] + } + + defines = [ "WEBRTC_NETWORK_TESTER_TEST_ENABLED" ] + + data = network_tester_unittests_resources + } + + rtc_executable("network_tester_server") { + sources = [ "server.cc" ] + + deps = [ + ":network_tester", + "../../rtc_base:null_socket_server", + "../../rtc_base:threading", + ] + } +} + +if (is_android) { + rtc_android_apk("NetworkTesterMobile") { + testonly = true + apk_name = "NetworkTesterMobile" + android_manifest = "androidapp/AndroidManifest.xml" + min_sdk_version = 21 + target_sdk_version = 24 + + deps = [ + ":NetworkTesterMobile_javalib", + ":NetworkTesterMobile_resources", + "../../rtc_base:base_java", + ] + + shared_libraries = [ "../../rtc_tools/network_tester:network_tester_so" ] + } + + rtc_android_library("NetworkTesterMobile_javalib") { + testonly = true + android_manifest = "androidapp/AndroidManifest.xml" + + sources = [ + "androidapp/src/com/google/media/networktester/MainActivity.java", + "androidapp/src/com/google/media/networktester/NetworkTester.java", + ] + + resources_package = "com.google.media.networktester" + deps = [ + ":NetworkTesterMobile_resources", + "../../rtc_base:base_java", + ] + } + + android_resources("NetworkTesterMobile_resources") { + testonly = true + custom_package = "com.google.media.networktester" + sources = [ + "androidapp/res/layout/activity_main.xml", + "androidapp/res/mipmap-hdpi/ic_launcher.png", + "androidapp/res/mipmap-mdpi/ic_launcher.png", + "androidapp/res/mipmap-xhdpi/ic_launcher.png", + "androidapp/res/mipmap-xxhdpi/ic_launcher.png", + "androidapp/res/mipmap-xxxhdpi/ic_launcher.png", + "androidapp/res/values-v17/styles.xml", + "androidapp/res/values-w820dp/dimens.xml", + "androidapp/res/values/colors.xml", + "androidapp/res/values/dimens.xml", + "androidapp/res/values/strings.xml", + ] + + # Needed for Bazel converter. + resource_dirs = [ "androidapp/res" ] + assert(resource_dirs != []) # Mark as used. + } + + rtc_shared_library("network_tester_so") { + sources = [ "jni.cc" ] + + deps = [ + ":network_tester", + "../../rtc_base:logging", + "../../rtc_base:threading", + ] + + suppressed_configs += [ "//build/config/android:hide_all_but_jni_onload" ] + configs += [ "//build/config/android:hide_all_but_jni" ] + + output_extension = "so" + } +} diff --git a/third_party/libwebrtc/rtc_tools/network_tester/README b/third_party/libwebrtc/rtc_tools/network_tester/README new file mode 100644 index 0000000000..6680212e81 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/README @@ -0,0 +1,35 @@ +This file explains how to run the network tester and how to analyze the results. + +create config files +=================== +use create_network_tester_config.py to create config files. +you can add or change the AddConfig call in the main function to create a +the desired network config. + +run network_tester_server +========================= +place the network config file next to the server binary and name it +"server_config.dat". + +the network_tester_server should run on a server with a public IP address. + +the log file of network_tester_server will be created next to the binary with +the name "server_packet_log.dat" + + +run NetworkTesterMobile (apk) +============================= +change the IP and the port in the jni.cpp file and set it to the port and IP +you run the network_tester_server on. + +place the network config file as "/mnt/sdcard/network_tester_client_config.dat" +on the tester android phone. + +The log file of network_tester_server will be created at +"/mnt/sdcard/network_tester_client_packet_log.dat" + + +analyze the results +==================== +run "python parse_packet_log.py -f <log_file_to_parse>" to analyze the +log results. diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/AndroidManifest.xml b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/AndroidManifest.xml new file mode 100755 index 0000000000..1ff519396b --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/AndroidManifest.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.google.media.networktester" > + <uses-permission android:name="android.permission.INTERNET" /> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> + <uses-sdk android:minSdkVersion="21" + android:targetSdkVersion="24" + android:maxSdkVersion="24" /> + <application + android:allowBackup="true" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:supportsRtl="true" + android:theme="@style/AppTheme" > + <activity android:name=".MainActivity" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> +</manifest> diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/layout/activity_main.xml b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/layout/activity_main.xml new file mode 100755 index 0000000000..8839a31003 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/layout/activity_main.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/activity_main" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:paddingStart="@dimen/activity_horizontal_margin" + android:paddingEnd="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin" + android:paddingBottom="@dimen/activity_vertical_margin" + tools:context="com.google.media.networktester.MainActivity"> + <Button + android:text="@string/start_test" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_alignParentStart="true" + android:id="@+id/start_button"/> + <Button + android:text="@string/interrupt_test" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentTop="true" + android:layout_toEndOf="@+id/start_button" + android:id="@+id/stop_button"/> + +</RelativeLayout> diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-hdpi/ic_launcher.png b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000000..cde69bccce --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-hdpi/ic_launcher.png diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-mdpi/ic_launcher.png b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000000..c133a0cbd3 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-mdpi/ic_launcher.png diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-xhdpi/ic_launcher.png b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000000..bfa42f0e7b --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-xhdpi/ic_launcher.png diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-xxhdpi/ic_launcher.png b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-xxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000000..324e72cdd7 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-xxhdpi/ic_launcher.png diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-xxxhdpi/ic_launcher.png b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-xxxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000000..aee44e1384 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/mipmap-xxxhdpi/ic_launcher.png diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values-v17/styles.xml b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values-v17/styles.xml new file mode 100755 index 0000000000..ff6c9d2c0f --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values-v17/styles.xml @@ -0,0 +1,8 @@ +<resources> + + <!-- Base application theme. --> + <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar"> + <!-- Customize your theme here. --> + </style> + +</resources> diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values-w820dp/dimens.xml b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values-w820dp/dimens.xml new file mode 100755 index 0000000000..63fc816444 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ +<resources> + <!-- Example customization of dimensions originally defined in res/values/dimens.xml + (such as screen margins) for screens with more than 820dp of available width. This + would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> + <dimen name="activity_horizontal_margin">64dp</dimen> +</resources> diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values/colors.xml b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values/colors.xml new file mode 100755 index 0000000000..3ab3e9cbce --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values/colors.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="colorPrimary">#3F51B5</color> + <color name="colorPrimaryDark">#303F9F</color> + <color name="colorAccent">#FF4081</color> +</resources> diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values/dimens.xml b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values/dimens.xml new file mode 100755 index 0000000000..47c8224673 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values/dimens.xml @@ -0,0 +1,5 @@ +<resources> + <!-- Default screen margins, per the Android Design guidelines. --> + <dimen name="activity_horizontal_margin">16dp</dimen> + <dimen name="activity_vertical_margin">16dp</dimen> +</resources> diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values/strings.xml b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values/strings.xml new file mode 100755 index 0000000000..273276d43e --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/res/values/strings.xml @@ -0,0 +1,6 @@ +<resources> + <string name="app_name">NetworkTester</string> + <string name="start_test">Start test</string> + <string name="interrupt_test">Interrupt test</string> + <string name="test_status">Status</string> +</resources> diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/src/com/google/media/networktester/MainActivity.java b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/src/com/google/media/networktester/MainActivity.java new file mode 100644 index 0000000000..33f442fce2 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/src/com/google/media/networktester/MainActivity.java @@ -0,0 +1,62 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +package com.google.media.networktester; + +import android.app.Activity; +import android.os.Bundle; +import android.os.Handler; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.WindowManager; +import android.widget.Button; + +public class MainActivity extends Activity { + Button startButton; + Button stopButton; + NetworkTester networkTester; + Handler mainThreadHandler; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + startButton = (Button) findViewById(R.id.start_button); + startButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + startTest(); + } + }); + stopButton = (Button) findViewById(R.id.stop_button); + stopButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + stopTest(); + } + }); + mainThreadHandler = new Handler(); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + } + + private void startTest() { + if (networkTester == null) { + networkTester = new NetworkTester(); + networkTester.start(); + } + } + + private void stopTest() { + if (networkTester != null) { + networkTester.interrupt(); + networkTester = null; + } + } +} diff --git a/third_party/libwebrtc/rtc_tools/network_tester/androidapp/src/com/google/media/networktester/NetworkTester.java b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/src/com/google/media/networktester/NetworkTester.java new file mode 100644 index 0000000000..7c08f873bb --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/androidapp/src/com/google/media/networktester/NetworkTester.java @@ -0,0 +1,32 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +package com.google.media.networktester; + +public class NetworkTester extends Thread { + private native static long CreateTestController(); + private native static void TestControllerConnect(long testController); + private native static void TestControllerRun(long testController); + private native static boolean TestControllerIsDone(long testController); + private native static void DestroyTestController(long testController); + static { + System.loadLibrary("network_tester_so"); + } + + @Override + public void run() { + final long testController = CreateTestController(); + TestControllerConnect(testController); + while (!Thread.interrupted() && !TestControllerIsDone(testController)) { + TestControllerRun(testController); + } + DestroyTestController(testController); + } +} diff --git a/third_party/libwebrtc/rtc_tools/network_tester/config_reader.cc b/third_party/libwebrtc/rtc_tools/network_tester/config_reader.cc new file mode 100644 index 0000000000..16ae458d50 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/config_reader.cc @@ -0,0 +1,54 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "rtc_tools/network_tester/config_reader.h" + +#include <fstream> +#include <iterator> +#include <string> + +#include "rtc_base/checks.h" + +namespace webrtc { + +ConfigReader::ConfigReader(const std::string& config_file_path) + : proto_config_index_(0) { + std::ifstream config_stream(config_file_path, + std::ios_base::in | std::ios_base::binary); + RTC_DCHECK(config_stream.is_open()) + << "Config " << config_file_path << " open failed"; + RTC_DCHECK(config_stream.good()); + std::string config_data((std::istreambuf_iterator<char>(config_stream)), + (std::istreambuf_iterator<char>())); + if (config_data.size() > 0) { + proto_all_configs_.ParseFromString(config_data); + } +} + +ConfigReader::~ConfigReader() = default; + +absl::optional<ConfigReader::Config> ConfigReader::GetNextConfig() { +#ifdef WEBRTC_NETWORK_TESTER_PROTO + if (proto_config_index_ >= proto_all_configs_.configs_size()) + return absl::nullopt; + auto proto_config = proto_all_configs_.configs(proto_config_index_++); + RTC_DCHECK(proto_config.has_packet_send_interval_ms()); + RTC_DCHECK(proto_config.has_packet_size()); + RTC_DCHECK(proto_config.has_execution_time_ms()); + Config config; + config.packet_send_interval_ms = proto_config.packet_send_interval_ms(); + config.packet_size = proto_config.packet_size(); + config.execution_time_ms = proto_config.execution_time_ms(); + return config; +#else + return absl::nullopt; +#endif // WEBRTC_NETWORK_TESTER_PROTO +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/rtc_tools/network_tester/config_reader.h b/third_party/libwebrtc/rtc_tools/network_tester/config_reader.h new file mode 100644 index 0000000000..3735555d51 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/config_reader.h @@ -0,0 +1,53 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_ +#define RTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_ + +#include <fstream> +#include <string> + +#include "absl/types/optional.h" +#include "rtc_base/ignore_wundef.h" + +#ifdef WEBRTC_NETWORK_TESTER_PROTO +RTC_PUSH_IGNORING_WUNDEF() +#include "rtc_tools/network_tester/network_tester_config.pb.h" +RTC_POP_IGNORING_WUNDEF() +using webrtc::network_tester::config::NetworkTesterAllConfigs; +#else +class NetworkTesterConfigs; +#endif // WEBRTC_NETWORK_TESTER_PROTO + +namespace webrtc { + +class ConfigReader { + public: + struct Config { + int packet_send_interval_ms; + int packet_size; + int execution_time_ms; + }; + explicit ConfigReader(const std::string& config_file_path); + ~ConfigReader(); + + ConfigReader(const ConfigReader&) = delete; + ConfigReader& operator=(const ConfigReader&) = delete; + + absl::optional<Config> GetNextConfig(); + + private: + NetworkTesterAllConfigs proto_all_configs_; + int proto_config_index_; +}; + +} // namespace webrtc + +#endif // RTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_ diff --git a/third_party/libwebrtc/rtc_tools/network_tester/create_network_tester_config.py b/third_party/libwebrtc/rtc_tools/network_tester/create_network_tester_config.py new file mode 100644 index 0000000000..de8d058f9d --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/create_network_tester_config.py @@ -0,0 +1,30 @@ +#!/usr/bin/env python +# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +import network_tester_config_pb2 + + +def AddConfig(all_configs, packet_send_interval_ms, packet_size, + execution_time_ms): + config = all_configs.configs.add() + config.packet_send_interval_ms = packet_send_interval_ms + config.packet_size = packet_size + config.execution_time_ms = execution_time_ms + + +def main(): + all_configs = network_tester_config_pb2.NetworkTesterAllConfigs() + AddConfig(all_configs, 10, 50, 200) + AddConfig(all_configs, 10, 100, 200) + with open("network_tester_config.dat", 'wb') as f: + f.write(all_configs.SerializeToString()) + + +if __name__ == "__main__": + main() diff --git a/third_party/libwebrtc/rtc_tools/network_tester/jni.cc b/third_party/libwebrtc/rtc_tools/network_tester/jni.cc new file mode 100644 index 0000000000..f192739ad0 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/jni.cc @@ -0,0 +1,68 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include <jni.h> +#undef JNIEXPORT +#define JNIEXPORT __attribute__((visibility("default"))) +#include <string> + +#include "rtc_base/logging.h" +#include "rtc_base/thread.h" +#include "rtc_tools/network_tester/test_controller.h" + +extern "C" JNIEXPORT jlong JNICALL +Java_com_google_media_networktester_NetworkTester_CreateTestController( + JNIEnv* jni, + jclass) { + rtc::ThreadManager::Instance()->WrapCurrentThread(); + return reinterpret_cast<intptr_t>(new webrtc::TestController( + 0, 0, "/mnt/sdcard/network_tester_client_config.dat", + "/mnt/sdcard/network_tester_client_packet_log.dat")); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_media_networktester_NetworkTester_TestControllerConnect( + JNIEnv* jni, + jclass, + jlong native_pointer) { + reinterpret_cast<webrtc::TestController*>(native_pointer) + ->SendConnectTo("85.195.237.107", 9090); +} + +extern "C" JNIEXPORT bool JNICALL +Java_com_google_media_networktester_NetworkTester_TestControllerIsDone( + JNIEnv* jni, + jclass, + jlong native_pointer) { + return reinterpret_cast<webrtc::TestController*>(native_pointer) + ->IsTestDone(); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_media_networktester_NetworkTester_TestControllerRun( + JNIEnv* jni, + jclass, + jlong native_pointer) { + // 100 ms arbitrary chosen, but it works well. + rtc::Thread::Current()->ProcessMessages(/*cms=*/100); +} + +extern "C" JNIEXPORT void JNICALL +Java_com_google_media_networktester_NetworkTester_DestroyTestController( + JNIEnv* jni, + jclass, + jlong native_pointer) { + webrtc::TestController* test_controller = + reinterpret_cast<webrtc::TestController*>(native_pointer); + if (test_controller) { + delete test_controller; + } + rtc::ThreadManager::Instance()->UnwrapCurrentThread(); +} diff --git a/third_party/libwebrtc/rtc_tools/network_tester/network_tester_config.proto b/third_party/libwebrtc/rtc_tools/network_tester/network_tester_config.proto new file mode 100644 index 0000000000..a911dc17ff --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/network_tester_config.proto @@ -0,0 +1,14 @@ +syntax = "proto2"; +option optimize_for = LITE_RUNTIME; +package webrtc.network_tester.config; + +message NetworkTesterConfig { + optional int32 packet_send_interval_ms = 1; + optional float packet_size = 2; + optional int32 execution_time_ms = 3; +} + +message NetworkTesterAllConfigs { + repeated NetworkTesterConfig configs = 1; +} + diff --git a/third_party/libwebrtc/rtc_tools/network_tester/network_tester_packet.proto b/third_party/libwebrtc/rtc_tools/network_tester/network_tester_packet.proto new file mode 100644 index 0000000000..c3bcec5ec7 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/network_tester_packet.proto @@ -0,0 +1,18 @@ +syntax = "proto2"; +option optimize_for = LITE_RUNTIME; +package webrtc.network_tester.packet; + +message NetworkTesterPacket { + enum Type { + HAND_SHAKING = 0; + TEST_START = 1; + TEST_DATA = 2; + TEST_DONE = 3; + } + + optional Type type = 1; + optional int64 send_timestamp = 2; + optional int64 arrival_timestamp = 3; + optional int64 sequence_number = 4; + optional int32 packet_size = 5; +} diff --git a/third_party/libwebrtc/rtc_tools/network_tester/network_tester_unittest.cc b/third_party/libwebrtc/rtc_tools/network_tester/network_tester_unittest.cc new file mode 100644 index 0000000000..60b34e4e9f --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/network_tester_unittest.cc @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifdef WEBRTC_NETWORK_TESTER_TEST_ENABLED + +#include <string> + +#include "rtc_base/gunit.h" +#include "rtc_tools/network_tester/test_controller.h" +#include "test/gtest.h" +#include "test/testsupport/file_utils.h" + +namespace webrtc { + +TEST(NetworkTesterTest, ServerClient) { + rtc::AutoThread main_thread; + TestController client( + 0, 0, webrtc::test::ResourcePath("network_tester/client_config", "dat"), + webrtc::test::OutputPath() + "client_packet_log.dat"); + TestController server( + 9090, 9090, + webrtc::test::ResourcePath("network_tester/server_config", "dat"), + webrtc::test::OutputPath() + "server_packet_log.dat"); + client.SendConnectTo("127.0.0.1", 9090); + EXPECT_TRUE_WAIT(server.IsTestDone() && client.IsTestDone(), 2000); +} + +} // namespace webrtc + +#endif // WEBRTC_NETWORK_TESTER_TEST_ENABLED diff --git a/third_party/libwebrtc/rtc_tools/network_tester/packet_logger.cc b/third_party/libwebrtc/rtc_tools/network_tester/packet_logger.cc new file mode 100644 index 0000000000..eef8030981 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/packet_logger.cc @@ -0,0 +1,44 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include "rtc_tools/network_tester/packet_logger.h" + +#include <string> + +#include "rtc_base/checks.h" + +namespace webrtc { + +PacketLogger::PacketLogger(const std::string& log_file_path) + : packet_logger_stream_(log_file_path, + std::ios_base::out | std::ios_base::binary) { + RTC_DCHECK(packet_logger_stream_.is_open()); + RTC_DCHECK(packet_logger_stream_.good()); +} + +PacketLogger::~PacketLogger() = default; + +void PacketLogger::LogPacket(const NetworkTesterPacket& packet) { + // The protobuffer message will be saved in the following format to the file: + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | 1 byte | X byte | 1 byte | ... | X byte | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + // | Size of the next | proto | Size of the next | ... | proto | + // | proto message | message | proto message | | message | + // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + std::string packet_data; + packet.SerializeToString(&packet_data); + RTC_DCHECK_LE(packet_data.length(), 255); + RTC_DCHECK_GE(packet_data.length(), 0); + char proto_size = packet_data.length(); + packet_logger_stream_.write(&proto_size, sizeof(proto_size)); + packet_logger_stream_.write(packet_data.data(), packet_data.length()); +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/rtc_tools/network_tester/packet_logger.h b/third_party/libwebrtc/rtc_tools/network_tester/packet_logger.h new file mode 100644 index 0000000000..c3ac309cf7 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/packet_logger.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_TOOLS_NETWORK_TESTER_PACKET_LOGGER_H_ +#define RTC_TOOLS_NETWORK_TESTER_PACKET_LOGGER_H_ + +#include <fstream> +#include <string> + +#include "rtc_base/ignore_wundef.h" + +#ifdef WEBRTC_NETWORK_TESTER_PROTO +RTC_PUSH_IGNORING_WUNDEF() +#include "rtc_tools/network_tester/network_tester_packet.pb.h" +RTC_POP_IGNORING_WUNDEF() +using webrtc::network_tester::packet::NetworkTesterPacket; +#else +class NetworkTesterPacket; +#endif // WEBRTC_NETWORK_TESTER_PROTO + +namespace webrtc { + +class PacketLogger { + public: + explicit PacketLogger(const std::string& log_file_path); + ~PacketLogger(); + + PacketLogger(const PacketLogger&) = delete; + PacketLogger& operator=(const PacketLogger&) = delete; + + void LogPacket(const NetworkTesterPacket& packet); + + private: + std::ofstream packet_logger_stream_; +}; + +} // namespace webrtc + +#endif // RTC_TOOLS_NETWORK_TESTER_PACKET_LOGGER_H_ diff --git a/third_party/libwebrtc/rtc_tools/network_tester/packet_sender.cc b/third_party/libwebrtc/rtc_tools/network_tester/packet_sender.cc new file mode 100644 index 0000000000..c9917373fe --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/packet_sender.cc @@ -0,0 +1,133 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rtc_tools/network_tester/packet_sender.h" + +#include <algorithm> +#include <memory> +#include <string> +#include <utility> + +#include "absl/functional/any_invocable.h" +#include "api/task_queue/pending_task_safety_flag.h" +#include "api/task_queue/task_queue_base.h" +#include "rtc_base/time_utils.h" +#include "rtc_tools/network_tester/config_reader.h" +#include "rtc_tools/network_tester/test_controller.h" + +namespace webrtc { + +namespace { + +absl::AnyInvocable<void() &&> SendPacketTask( + PacketSender* packet_sender, + rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> task_safety_flag, + int64_t target_time_ms = rtc::TimeMillis()) { + return [target_time_ms, packet_sender, + task_safety_flag = std::move(task_safety_flag)]() mutable { + if (task_safety_flag->alive() && packet_sender->IsSending()) { + packet_sender->SendPacket(); + target_time_ms += packet_sender->GetSendIntervalMs(); + int64_t delay_ms = + std::max(static_cast<int64_t>(0), target_time_ms - rtc::TimeMillis()); + TaskQueueBase::Current()->PostDelayedTask( + SendPacketTask(packet_sender, std::move(task_safety_flag), + target_time_ms), + TimeDelta::Millis(delay_ms)); + } + }; +} + +absl::AnyInvocable<void() &&> UpdateTestSettingTask( + PacketSender* packet_sender, + std::unique_ptr<ConfigReader> config_reader, + rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> task_safety_flag) { + return [packet_sender, config_reader = std::move(config_reader), + task_safety_flag = std::move(task_safety_flag)]() mutable { + if (!task_safety_flag->alive()) { + return; + } + if (absl::optional<ConfigReader::Config> config = + config_reader->GetNextConfig()) { + packet_sender->UpdateTestSetting(config->packet_size, + config->packet_send_interval_ms); + TaskQueueBase::Current()->PostDelayedTask( + UpdateTestSettingTask(packet_sender, std::move(config_reader), + std::move(task_safety_flag)), + TimeDelta::Millis(config->execution_time_ms)); + } else { + packet_sender->StopSending(); + } + }; +} + +} // namespace + +PacketSender::PacketSender( + TestController* test_controller, + webrtc::TaskQueueBase* worker_queue, + rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> task_safety_flag, + const std::string& config_file_path) + : packet_size_(0), + send_interval_ms_(0), + sequence_number_(0), + sending_(false), + config_file_path_(config_file_path), + test_controller_(test_controller), + worker_queue_(worker_queue), + task_safety_flag_(task_safety_flag) {} + +PacketSender::~PacketSender() = default; + +void PacketSender::StartSending() { + worker_queue_checker_.Detach(); + worker_queue_->PostTask(SafeTask(task_safety_flag_, [this]() { + RTC_DCHECK_RUN_ON(&worker_queue_checker_); + sending_ = true; + })); + worker_queue_->PostTask(UpdateTestSettingTask( + this, std::make_unique<ConfigReader>(config_file_path_), + task_safety_flag_)); + worker_queue_->PostTask(SendPacketTask(this, task_safety_flag_)); +} + +void PacketSender::StopSending() { + RTC_DCHECK_RUN_ON(&worker_queue_checker_); + sending_ = false; + test_controller_->OnTestDone(); +} + +bool PacketSender::IsSending() const { + RTC_DCHECK_RUN_ON(&worker_queue_checker_); + return sending_; +} + +void PacketSender::SendPacket() { + RTC_DCHECK_RUN_ON(&worker_queue_checker_); + NetworkTesterPacket packet; + packet.set_type(NetworkTesterPacket::TEST_DATA); + packet.set_sequence_number(sequence_number_++); + packet.set_send_timestamp(rtc::TimeMicros()); + test_controller_->SendData(packet, packet_size_); +} + +int64_t PacketSender::GetSendIntervalMs() const { + RTC_DCHECK_RUN_ON(&worker_queue_checker_); + return send_interval_ms_; +} + +void PacketSender::UpdateTestSetting(size_t packet_size, + int64_t send_interval_ms) { + RTC_DCHECK_RUN_ON(&worker_queue_checker_); + send_interval_ms_ = send_interval_ms; + packet_size_ = packet_size; +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/rtc_tools/network_tester/packet_sender.h b/third_party/libwebrtc/rtc_tools/network_tester/packet_sender.h new file mode 100644 index 0000000000..7fd500f27c --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/packet_sender.h @@ -0,0 +1,71 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_TOOLS_NETWORK_TESTER_PACKET_SENDER_H_ +#define RTC_TOOLS_NETWORK_TESTER_PACKET_SENDER_H_ + +#include <memory> +#include <string> + +#include "api/sequence_checker.h" +#include "api/task_queue/pending_task_safety_flag.h" +#include "api/task_queue/task_queue_factory.h" +#include "rtc_base/ignore_wundef.h" +#include "rtc_base/system/no_unique_address.h" + +#ifdef WEBRTC_NETWORK_TESTER_PROTO +RTC_PUSH_IGNORING_WUNDEF() +#include "rtc_tools/network_tester/network_tester_packet.pb.h" +RTC_POP_IGNORING_WUNDEF() +using webrtc::network_tester::packet::NetworkTesterPacket; +#else +class NetworkTesterPacket; +#endif // WEBRTC_NETWORK_TESTER_PROTO + +namespace webrtc { + +class TestController; + +class PacketSender { + public: + PacketSender( + TestController* test_controller, + webrtc::TaskQueueBase* worker_queue, + rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> task_safety_flag, + const std::string& config_file_path); + ~PacketSender(); + + PacketSender(const PacketSender&) = delete; + PacketSender& operator=(const PacketSender&) = delete; + + void StartSending(); + void StopSending(); + bool IsSending() const; + + void SendPacket(); + + int64_t GetSendIntervalMs() const; + void UpdateTestSetting(size_t packet_size, int64_t send_interval_ms); + + private: + RTC_NO_UNIQUE_ADDRESS SequenceChecker worker_queue_checker_; + size_t packet_size_ RTC_GUARDED_BY(worker_queue_checker_); + int64_t send_interval_ms_ RTC_GUARDED_BY(worker_queue_checker_); + int64_t sequence_number_ RTC_GUARDED_BY(worker_queue_checker_); + bool sending_ RTC_GUARDED_BY(worker_queue_checker_); + const std::string config_file_path_; + TestController* const test_controller_; + webrtc::TaskQueueBase* worker_queue_; + rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> task_safety_flag_; +}; + +} // namespace webrtc + +#endif // RTC_TOOLS_NETWORK_TESTER_PACKET_SENDER_H_ diff --git a/third_party/libwebrtc/rtc_tools/network_tester/parse_packet_log.py b/third_party/libwebrtc/rtc_tools/network_tester/parse_packet_log.py new file mode 100755 index 0000000000..be86e0c88d --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/parse_packet_log.py @@ -0,0 +1,150 @@ +# Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. +# +# Use of this source code is governed by a BSD-style license +# that can be found in the LICENSE file in the root of the source +# tree. An additional intellectual property rights grant can be found +# in the file PATENTS. All contributing project authors may +# be found in the AUTHORS file in the root of the source tree. + +# To run this script please copy "out/<build_name>/pyproto/webrtc/rtc_tools/ +# network_tester/network_tester_packet_pb2.py" next to this script. +# The you can run this script with: +# "python parse_packet_log.py -f packet_log.dat" +# for more information call: +# "python parse_packet_log.py --help" + +from optparse import OptionParser +import struct + +import matplotlib.pyplot as plt + +import network_tester_packet_pb2 + + +def GetSize(file_to_parse): + data = file_to_parse.read(1) + if data == '': + return 0 + return struct.unpack('<b', data)[0] + + +def ParsePacketLog(packet_log_file_to_parse): + packets = [] + with open(packet_log_file_to_parse, 'rb') as file_to_parse: + while True: + size = GetSize(file_to_parse) + if size == 0: + break + try: + packet = network_tester_packet_pb2.NetworkTesterPacket() + packet.ParseFromString(file_to_parse.read(size)) + packets.append(packet) + except IOError: + break + return packets + + +def GetTimeAxis(packets): + first_arrival_time = packets[0].arrival_timestamp + return [(packet.arrival_timestamp - first_arrival_time) / 1000000.0 + for packet in packets] + + +def CreateSendTimeDiffPlot(packets, plot): + first_send_time_diff = (packets[0].arrival_timestamp - + packets[0].send_timestamp) + y = [(packet.arrival_timestamp - packet.send_timestamp) - + first_send_time_diff for packet in packets] + plot.grid(True) + plot.set_title("SendTime difference [us]") + plot.plot(GetTimeAxis(packets), y) + + +class MovingAverageBitrate(object): + def __init__(self): + self.packet_window = [] + self.window_time = 1000000 + self.bytes = 0 + self.latest_packet_time = 0 + self.send_interval = 0 + + def RemoveOldPackets(self): + for packet in self.packet_window: + if (self.latest_packet_time - packet.arrival_timestamp > + self.window_time): + self.bytes = self.bytes - packet.packet_size + self.packet_window.remove(packet) + + def AddPacket(self, packet): + """This functions returns bits / second""" + self.send_interval = packet.arrival_timestamp - self.latest_packet_time + self.latest_packet_time = packet.arrival_timestamp + self.RemoveOldPackets() + self.packet_window.append(packet) + self.bytes = self.bytes + packet.packet_size + return self.bytes * 8 + + +def CreateReceiveBiratePlot(packets, plot): + bitrate = MovingAverageBitrate() + y = [bitrate.AddPacket(packet) for packet in packets] + plot.grid(True) + plot.set_title("Receive birate [bps]") + plot.plot(GetTimeAxis(packets), y) + + +def CreatePacketlossPlot(packets, plot): + packets_look_up = {} + first_sequence_number = packets[0].sequence_number + last_sequence_number = packets[-1].sequence_number + for packet in packets: + packets_look_up[packet.sequence_number] = packet + y = [] + x = [] + first_arrival_time = 0 + last_arrival_time = 0 + last_arrival_time_diff = 0 + for sequence_number in range(first_sequence_number, + last_sequence_number + 1): + if sequence_number in packets_look_up: + y.append(0) + if first_arrival_time == 0: + first_arrival_time = packets_look_up[ + sequence_number].arrival_timestamp + x_time = (packets_look_up[sequence_number].arrival_timestamp - + first_arrival_time) + if last_arrival_time != 0: + last_arrival_time_diff = x_time - last_arrival_time + last_arrival_time = x_time + x.append(x_time / 1000000.0) + else: + if last_arrival_time != 0 and last_arrival_time_diff != 0: + x.append( + (last_arrival_time + last_arrival_time_diff) / 1000000.0) + y.append(1) + plot.grid(True) + plot.set_title("Lost packets [0/1]") + plot.plot(x, y) + + +def main(): + parser = OptionParser() + parser.add_option("-f", + "--packet_log_file", + dest="packet_log_file", + help="packet_log file to parse") + + options = parser.parse_args()[0] + + packets = ParsePacketLog(options.packet_log_file) + f, plots = plt.subplots(3, sharex=True) + plt.xlabel('time [sec]') + CreateSendTimeDiffPlot(packets, plots[0]) + CreateReceiveBiratePlot(packets, plots[1]) + CreatePacketlossPlot(packets, plots[2]) + f.subplots_adjust(hspace=0.3) + plt.show() + + +if __name__ == "__main__": + main() diff --git a/third_party/libwebrtc/rtc_tools/network_tester/server.cc b/third_party/libwebrtc/rtc_tools/network_tester/server.cc new file mode 100644 index 0000000000..f0f610a925 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/server.cc @@ -0,0 +1,23 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rtc_base/null_socket_server.h" +#include "rtc_tools/network_tester/test_controller.h" + +int main(int /*argn*/, char* /*argv*/[]) { + rtc::Thread main_thread(std::make_unique<rtc::NullSocketServer>()); + webrtc::TestController server(9090, 9090, "server_config.dat", + "server_packet_log.dat"); + while (!server.IsTestDone()) { + // 100 ms is arbitrary chosen. + main_thread.ProcessMessages(/*cms=*/100); + } + return 0; +} diff --git a/third_party/libwebrtc/rtc_tools/network_tester/test_controller.cc b/third_party/libwebrtc/rtc_tools/network_tester/test_controller.cc new file mode 100644 index 0000000000..6fe83fd430 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/test_controller.cc @@ -0,0 +1,158 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "rtc_tools/network_tester/test_controller.h" + +#include <limits> + +#include "absl/types/optional.h" +#include "rtc_base/checks.h" +#include "rtc_base/internal/default_socket_server.h" +#include "rtc_base/ip_address.h" +#include "rtc_base/logging.h" +#include "rtc_base/thread.h" + +namespace webrtc { + +TestController::TestController(int min_port, + int max_port, + const std::string& config_file_path, + const std::string& log_file_path) + : socket_server_(rtc::CreateDefaultSocketServer()), + packet_sender_thread_( + std::make_unique<rtc::Thread>(socket_server_.get())), + socket_factory_(socket_server_.get()), + config_file_path_(config_file_path), + packet_logger_(log_file_path), + local_test_done_(false), + remote_test_done_(false), + task_safety_flag_(PendingTaskSafetyFlag::CreateDetached()) { + RTC_DCHECK_RUN_ON(&test_controller_thread_checker_); + send_data_.fill(42); + packet_sender_thread_->SetName("PacketSender", nullptr); + packet_sender_thread_->Start(); + packet_sender_thread_->BlockingCall([&] { + RTC_DCHECK_RUN_ON(packet_sender_thread_.get()); + udp_socket_ = + std::unique_ptr<rtc::AsyncPacketSocket>(socket_factory_.CreateUdpSocket( + rtc::SocketAddress(rtc::GetAnyIP(AF_INET), 0), min_port, max_port)); + udp_socket_->SignalReadPacket.connect(this, &TestController::OnReadPacket); + }); +} + +TestController::~TestController() { + RTC_DCHECK_RUN_ON(&test_controller_thread_checker_); + packet_sender_thread_->BlockingCall( + [this]() { task_safety_flag_->SetNotAlive(); }); +} + +void TestController::SendConnectTo(const std::string& hostname, int port) { + RTC_DCHECK_RUN_ON(&test_controller_thread_checker_); + remote_address_ = rtc::SocketAddress(hostname, port); + NetworkTesterPacket packet; + packet.set_type(NetworkTesterPacket::HAND_SHAKING); + SendData(packet, absl::nullopt); + MutexLock scoped_lock(&test_done_lock_); + local_test_done_ = false; + remote_test_done_ = false; +} + +void TestController::SendData(const NetworkTesterPacket& packet, + absl::optional<size_t> data_size) { + if (!packet_sender_thread_->IsCurrent()) { + packet_sender_thread_->PostTask(SafeTask( + task_safety_flag_, + [this, packet, data_size]() { this->SendData(packet, data_size); })); + return; + } + RTC_DCHECK_RUN_ON(packet_sender_thread_.get()); + RTC_LOG(LS_VERBOSE) << "SendData"; + + // Can be call from packet_sender or from test_controller thread. + size_t packet_size = packet.ByteSizeLong(); + send_data_[0] = packet_size; + packet_size++; + packet.SerializeToArray(&send_data_[1], std::numeric_limits<char>::max()); + if (data_size && *data_size > packet_size) + packet_size = *data_size; + udp_socket_->SendTo((const void*)send_data_.data(), packet_size, + remote_address_, rtc::PacketOptions()); +} + +void TestController::OnTestDone() { + RTC_DCHECK_RUN_ON(packet_sender_thread_.get()); + NetworkTesterPacket packet; + packet.set_type(NetworkTesterPacket::TEST_DONE); + SendData(packet, absl::nullopt); + MutexLock scoped_lock(&test_done_lock_); + local_test_done_ = true; +} + +bool TestController::IsTestDone() { + RTC_DCHECK_RUN_ON(&test_controller_thread_checker_); + MutexLock scoped_lock(&test_done_lock_); + return local_test_done_ && remote_test_done_; +} + +void TestController::OnReadPacket(rtc::AsyncPacketSocket* socket, + const char* data, + size_t len, + const rtc::SocketAddress& remote_addr, + const int64_t& packet_time_us) { + RTC_DCHECK_RUN_ON(packet_sender_thread_.get()); + RTC_LOG(LS_VERBOSE) << "OnReadPacket"; + size_t packet_size = data[0]; + std::string receive_data(&data[1], packet_size); + NetworkTesterPacket packet; + packet.ParseFromString(receive_data); + RTC_CHECK(packet.has_type()); + switch (packet.type()) { + case NetworkTesterPacket::HAND_SHAKING: { + NetworkTesterPacket packet; + packet.set_type(NetworkTesterPacket::TEST_START); + remote_address_ = remote_addr; + SendData(packet, absl::nullopt); + packet_sender_.reset(new PacketSender(this, packet_sender_thread_.get(), + task_safety_flag_, + config_file_path_)); + packet_sender_->StartSending(); + MutexLock scoped_lock(&test_done_lock_); + local_test_done_ = false; + remote_test_done_ = false; + break; + } + case NetworkTesterPacket::TEST_START: { + packet_sender_.reset(new PacketSender(this, packet_sender_thread_.get(), + task_safety_flag_, + config_file_path_)); + packet_sender_->StartSending(); + MutexLock scoped_lock(&test_done_lock_); + local_test_done_ = false; + remote_test_done_ = false; + break; + } + case NetworkTesterPacket::TEST_DATA: { + packet.set_arrival_timestamp(packet_time_us); + packet.set_packet_size(len); + packet_logger_.LogPacket(packet); + break; + } + case NetworkTesterPacket::TEST_DONE: { + MutexLock scoped_lock(&test_done_lock_); + remote_test_done_ = true; + break; + } + default: { + RTC_DCHECK_NOTREACHED(); + } + } +} + +} // namespace webrtc diff --git a/third_party/libwebrtc/rtc_tools/network_tester/test_controller.h b/third_party/libwebrtc/rtc_tools/network_tester/test_controller.h new file mode 100644 index 0000000000..b08fbd5dd8 --- /dev/null +++ b/third_party/libwebrtc/rtc_tools/network_tester/test_controller.h @@ -0,0 +1,95 @@ +/* + * Copyright 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef RTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_ +#define RTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_ + +#include <stddef.h> +#include <stdint.h> + +#include <array> +#include <memory> +#include <string> + +#include "absl/types/optional.h" +#include "api/sequence_checker.h" +#include "p2p/base/basic_packet_socket_factory.h" +#include "rtc_base/async_packet_socket.h" +#include "rtc_base/ignore_wundef.h" +#include "rtc_base/socket_address.h" +#include "rtc_base/synchronization/mutex.h" +#include "rtc_base/system/no_unique_address.h" +#include "rtc_base/third_party/sigslot/sigslot.h" +#include "rtc_base/thread_annotations.h" +#include "rtc_tools/network_tester/packet_logger.h" +#include "rtc_tools/network_tester/packet_sender.h" + +#ifdef WEBRTC_NETWORK_TESTER_PROTO +RTC_PUSH_IGNORING_WUNDEF() +#include "rtc_tools/network_tester/network_tester_packet.pb.h" +RTC_POP_IGNORING_WUNDEF() +using webrtc::network_tester::packet::NetworkTesterPacket; +#else +class NetworkTesterPacket; +#endif // WEBRTC_NETWORK_TESTER_PROTO + +namespace webrtc { + +constexpr size_t kEthernetMtu = 1500; + +class TestController : public sigslot::has_slots<> { + public: + TestController(int min_port, + int max_port, + const std::string& config_file_path, + const std::string& log_file_path); + ~TestController() override; + + TestController(const TestController&) = delete; + TestController& operator=(const TestController&) = delete; + + void SendConnectTo(const std::string& hostname, int port); + + void SendData(const NetworkTesterPacket& packet, + absl::optional<size_t> data_size); + + void OnTestDone(); + + bool IsTestDone(); + + private: + void OnReadPacket(rtc::AsyncPacketSocket* socket, + const char* data, + size_t len, + const rtc::SocketAddress& remote_addr, + const int64_t& packet_time_us); + RTC_NO_UNIQUE_ADDRESS SequenceChecker test_controller_thread_checker_; + std::unique_ptr<rtc::SocketServer> socket_server_; + std::unique_ptr<rtc::Thread> packet_sender_thread_; + rtc::BasicPacketSocketFactory socket_factory_ + RTC_GUARDED_BY(packet_sender_thread_); + const std::string config_file_path_; + PacketLogger packet_logger_ RTC_GUARDED_BY(packet_sender_thread_); + Mutex test_done_lock_ RTC_GUARDED_BY(test_controller_thread_checker_); + bool local_test_done_ RTC_GUARDED_BY(test_done_lock_); + bool remote_test_done_ RTC_GUARDED_BY(test_done_lock_); + std::array<char, kEthernetMtu> send_data_ + RTC_GUARDED_BY(packet_sender_thread_); + std::unique_ptr<rtc::AsyncPacketSocket> udp_socket_ + RTC_GUARDED_BY(packet_sender_thread_); + rtc::SocketAddress remote_address_; + std::unique_ptr<PacketSender> packet_sender_ + RTC_GUARDED_BY(packet_sender_thread_); + rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> task_safety_flag_; +}; + +} // namespace webrtc + +#endif // RTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_ |