Moving src/webrtc into src/.

In order to eliminate the WebRTC Subtree mirror in Chromium, 
WebRTC is moving the content of the src/webrtc directory up
to the src/ directory.

NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
TBR=tommi@webrtc.org

Bug: chromium:611808
Change-Id: Iac59c5b51b950f174119565bac87955a7994bc38
Reviewed-on: https://webrtc-review.googlesource.com/1560
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Henrik Kjellander <kjellander@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#19845}
This commit is contained in:
Mirko Bonadei
2017-09-15 06:15:48 +02:00
committed by Commit Bot
parent 6674846b4a
commit bb547203bf
4576 changed files with 1092 additions and 1196 deletions

View File

@ -0,0 +1,178 @@
# 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")
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 = "webrtc/rtc_tools/network_tester"
}
proto_library("network_tester_packet_proto") {
sources = [
"network_tester_packet.proto",
]
proto_out_dir = "webrtc/rtc_tools/network_tester"
}
rtc_static_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:optional",
"../../p2p",
"../../rtc_base:protobuf_utils",
"../../rtc_base:rtc_base_approved",
"../../rtc_base:rtc_task_queue",
"../../rtc_base:sequenced_task_checker",
]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
}
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_source_set("network_tester_unittests") {
testonly = true
# Skip restricting visibility on mobile platforms since the tests on those
# gets additional generated targets which would require many lines here to
# cover (which would be confusing to read and hard to maintain).
if (!is_android && !is_ios) {
visibility = [ "..:tools_unittests" ]
}
sources = [
"network_tester_unittest.cc",
]
deps = [
":network_tester",
"../../rtc_base:rtc_base_tests_utils",
"../../test:test_support",
"//testing/gtest",
]
if (is_ios) {
deps += [ ":network_tester_unittests_bundle_data" ]
}
defines = [
"GTEST_RELATIVE_PATH",
"WEBRTC_NETWORK_TESTER_TEST_ENABLED",
]
data = network_tester_unittests_resources
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
}
rtc_executable("network_tester_server") {
sources = [
"server.cc",
]
deps = [
":network_tester",
]
if (!build_with_chromium && is_clang) {
# Suppress warnings from the Chromium Clang plugin (bugs.webrtc.org/163).
suppressed_configs += [ "//build/config/clang:find_bad_constructs" ]
}
}
}
if (is_android) {
android_apk("NetworkTesterMobile") {
testonly = true
apk_name = "NetworkTesterMobile"
android_manifest = "androidapp/AndroidManifest.xml"
deps = [
":NetworkTesterMobile_javalib",
":NetworkTesterMobile_resources",
"../../rtc_base:base_java",
"//base:base_java",
]
shared_libraries = [ "../../rtc_tools/network_tester:network_tester_so" ]
}
android_library("NetworkTesterMobile_javalib") {
testonly = true
android_manifest = "androidapp/AndroidManifest.xml"
java_files = [
"androidapp/src/com/google/media/networktester/MainActivity.java",
"androidapp/src/com/google/media/networktester/NetworkTester.java",
]
deps = [
":NetworkTesterMobile_resources",
"../../rtc_base:base_java",
]
}
android_resources("NetworkTesterMobile_resources") {
testonly = true
resource_dirs = [ "androidapp/res" ]
custom_package = "com.google.media.networktester"
}
rtc_shared_library("network_tester_so") {
sources = [
"jni.cpp",
]
deps = [
":network_tester",
"../../system_wrappers:field_trial_default",
]
suppressed_configs += [ "//build/config/android:hide_all_but_jni_onload" ]
configs += [ "//build/config/android:hide_all_but_jni" ]
output_extension = "so"
}
}

View File

@ -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.

View File

@ -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="17"
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>

View File

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,8 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- Customize your theme here. -->
</style>
</resources>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -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>

View File

@ -0,0 +1,66 @@
/*
* 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.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
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 = null;
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;
}
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,50 @@
/*
* 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 "webrtc/rtc_tools/network_tester/config_reader.h"
#include <string>
#include <vector>
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());
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;
rtc::Optional<ConfigReader::Config> ConfigReader::GetNextConfig() {
#ifdef WEBRTC_NETWORK_TESTER_PROTO
if (proto_config_index_ >= proto_all_configs_.configs_size())
return rtc::Optional<Config>();
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 rtc::Optional<Config>(config);
#else
return rtc::Optional<Config>();
#endif // WEBRTC_NETWORK_TESTER_PROTO
}
} // namespace webrtc

View File

@ -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 WEBRTC_RTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_
#define WEBRTC_RTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_
#include <fstream>
#include <string>
#include "webrtc/api/optional.h"
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/rtc_base/ignore_wundef.h"
#ifdef WEBRTC_NETWORK_TESTER_PROTO
RTC_PUSH_IGNORING_WUNDEF()
#include "webrtc/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();
rtc::Optional<Config> GetNextConfig();
private:
NetworkTesterAllConfigs proto_all_configs_;
int proto_config_index_;
RTC_DISALLOW_COPY_AND_ASSIGN(ConfigReader);
};
} // namespace webrtc
#endif // WEBRTC_RTC_TOOLS_NETWORK_TESTER_CONFIG_READER_H_

View File

@ -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()

View File

@ -0,0 +1,63 @@
/*
* 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 "webrtc/rtc_tools/network_tester/test_controller.h"
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_media_networktester_NetworkTester_CreateTestController(
JNIEnv* jni,
jclass) {
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) {
reinterpret_cast<webrtc::TestController*>(native_pointer)->Run();
}
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;
}
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -0,0 +1,36 @@
/*
* 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 "webrtc/rtc_tools/network_tester/test_controller.h"
#include "webrtc/rtc_base/gunit.h"
#include "webrtc/test/gtest.h"
#include "webrtc/test/testsupport/fileutils.h"
namespace webrtc {
TEST(NetworkTesterTest, ServerClient) {
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

View File

@ -0,0 +1,43 @@
/*
* 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 "webrtc/rtc_tools/network_tester/packet_logger.h"
#include "webrtc/rtc_base/checks.h"
#include "webrtc/rtc_base/protobuf_utils.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 |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
ProtoString 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

View File

@ -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 WEBRTC_RTC_TOOLS_NETWORK_TESTER_PACKET_LOGGER_H_
#define WEBRTC_RTC_TOOLS_NETWORK_TESTER_PACKET_LOGGER_H_
#include <fstream>
#include <string>
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/rtc_base/ignore_wundef.h"
#ifdef WEBRTC_NETWORK_TESTER_PROTO
RTC_PUSH_IGNORING_WUNDEF()
#include "webrtc/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();
void LogPacket(const NetworkTesterPacket& packet);
private:
std::ofstream packet_logger_stream_;
RTC_DISALLOW_COPY_AND_ASSIGN(PacketLogger);
};
} // namespace webrtc
#endif // WEBRTC_RTC_TOOLS_NETWORK_TESTER_PACKET_LOGGER_H_

View File

@ -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 "webrtc/rtc_tools/network_tester/packet_sender.h"
#include <algorithm>
#include <string>
#include <utility>
#include "webrtc/rtc_base/timeutils.h"
#include "webrtc/rtc_tools/network_tester/config_reader.h"
#include "webrtc/rtc_tools/network_tester/test_controller.h"
namespace webrtc {
namespace {
class SendPacketTask : public rtc::QueuedTask {
public:
explicit SendPacketTask(PacketSender* packet_sender)
: target_time_ms_(rtc::TimeMillis()), packet_sender_(packet_sender) {}
private:
bool Run() override {
if (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());
rtc::TaskQueue::Current()->PostDelayedTask(
std::unique_ptr<QueuedTask>(this), delay_ms);
return false;
} else {
return true;
}
}
int64_t target_time_ms_;
PacketSender* const packet_sender_;
};
class UpdateTestSettingTask : public rtc::QueuedTask {
public:
UpdateTestSettingTask(PacketSender* packet_sender,
std::unique_ptr<ConfigReader> config_reader)
: packet_sender_(packet_sender),
config_reader_(std::move(config_reader)) {}
private:
bool Run() override {
auto config = config_reader_->GetNextConfig();
if (config) {
packet_sender_->UpdateTestSetting((*config).packet_size,
(*config).packet_send_interval_ms);
rtc::TaskQueue::Current()->PostDelayedTask(
std::unique_ptr<QueuedTask>(this), (*config).execution_time_ms);
return false;
} else {
packet_sender_->StopSending();
return true;
}
}
PacketSender* const packet_sender_;
const std::unique_ptr<ConfigReader> config_reader_;
};
} // namespace
PacketSender::PacketSender(TestController* test_controller,
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_("Packet Sender", rtc::TaskQueue::Priority::HIGH) {}
PacketSender::~PacketSender() = default;
void PacketSender::StartSending() {
worker_queue_checker_.Detach();
worker_queue_.PostTask([this]() {
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
sending_ = true;
});
worker_queue_.PostTask(
std::unique_ptr<rtc::QueuedTask>(new UpdateTestSettingTask(
this,
std::unique_ptr<ConfigReader>(new ConfigReader(config_file_path_)))));
worker_queue_.PostTask(
std::unique_ptr<rtc::QueuedTask>(new SendPacketTask(this)));
}
void PacketSender::StopSending() {
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
sending_ = false;
test_controller_->OnTestDone();
}
bool PacketSender::IsSending() const {
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
return sending_;
}
void PacketSender::SendPacket() {
RTC_DCHECK_CALLED_SEQUENTIALLY(&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, rtc::Optional<size_t>(packet_size_));
}
int64_t PacketSender::GetSendIntervalMs() const {
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
return send_interval_ms_;
}
void PacketSender::UpdateTestSetting(size_t packet_size,
int64_t send_interval_ms) {
RTC_DCHECK_CALLED_SEQUENTIALLY(&worker_queue_checker_);
send_interval_ms_ = send_interval_ms;
packet_size_ = packet_size;
}
} // namespace webrtc

View File

@ -0,0 +1,65 @@
/*
* 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 WEBRTC_RTC_TOOLS_NETWORK_TESTER_PACKET_SENDER_H_
#define WEBRTC_RTC_TOOLS_NETWORK_TESTER_PACKET_SENDER_H_
#include <memory>
#include <string>
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/rtc_base/ignore_wundef.h"
#include "webrtc/rtc_base/sequenced_task_checker.h"
#include "webrtc/rtc_base/task_queue.h"
#ifdef WEBRTC_NETWORK_TESTER_PROTO
RTC_PUSH_IGNORING_WUNDEF()
#include "webrtc/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,
const std::string& config_file_path);
~PacketSender();
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::SequencedTaskChecker worker_queue_checker_;
size_t packet_size_ RTC_ACCESS_ON(worker_queue_checker_);
int64_t send_interval_ms_ RTC_ACCESS_ON(worker_queue_checker_);
int64_t sequence_number_ RTC_ACCESS_ON(worker_queue_checker_);
bool sending_ RTC_ACCESS_ON(worker_queue_checker_);
const std::string config_file_path_;
TestController* const test_controller_;
rtc::TaskQueue worker_queue_;
RTC_DISALLOW_COPY_AND_ASSIGN(PacketSender);
};
} // namespace webrtc
#endif // WEBRTC_RTC_TOOLS_NETWORK_TESTER_PACKET_SENDER_H_

View File

@ -0,0 +1,147 @@
# 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()

View File

@ -0,0 +1,19 @@
/*
* 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 "webrtc/rtc_tools/network_tester/test_controller.h"
int main() {
webrtc::TestController server(9090, 9090, "server_config.dat",
"server_packet_log.dat");
while (!server.IsTestDone()) {
server.Run();
}
}

View File

@ -0,0 +1,125 @@
/*
* 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 "webrtc/rtc_tools/network_tester/test_controller.h"
namespace webrtc {
TestController::TestController(int min_port,
int max_port,
const std::string& config_file_path,
const std::string& log_file_path)
: socket_factory_(rtc::ThreadManager::Instance()->WrapCurrentThread()),
config_file_path_(config_file_path),
packet_logger_(log_file_path),
local_test_done_(false),
remote_test_done_(false) {
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
packet_sender_checker_.Detach();
send_data_.fill(42);
auto socket =
std::unique_ptr<rtc::AsyncPacketSocket>(socket_factory_.CreateUdpSocket(
rtc::SocketAddress(rtc::GetAnyIP(AF_INET), 0), min_port, max_port));
socket->SignalReadPacket.connect(this, &TestController::OnReadPacket);
udp_transport_.reset(
new cricket::UdpTransport("network tester transport", std::move(socket)));
}
void TestController::SendConnectTo(const std::string& hostname, int port) {
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
udp_transport_->SetRemoteAddress(rtc::SocketAddress(hostname, port));
NetworkTesterPacket packet;
packet.set_type(NetworkTesterPacket::HAND_SHAKING);
SendData(packet, rtc::Optional<size_t>());
rtc::CritScope scoped_lock(&local_test_done_lock_);
local_test_done_ = false;
remote_test_done_ = false;
}
void TestController::Run() {
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
rtc::Thread::Current()->ProcessMessages(0);
}
void TestController::SendData(const NetworkTesterPacket& packet,
rtc::Optional<size_t> data_size) {
// Can be call from packet_sender or from test_controller thread.
size_t packet_size = packet.ByteSize();
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_transport_->SendPacket(send_data_.data(), packet_size,
rtc::PacketOptions(), 0);
}
void TestController::OnTestDone() {
RTC_DCHECK_CALLED_SEQUENTIALLY(&packet_sender_checker_);
NetworkTesterPacket packet;
packet.set_type(NetworkTesterPacket::TEST_DONE);
SendData(packet, rtc::Optional<size_t>());
rtc::CritScope scoped_lock(&local_test_done_lock_);
local_test_done_ = true;
}
bool TestController::IsTestDone() {
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
rtc::CritScope scoped_lock(&local_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 rtc::PacketTime& packet_time) {
RTC_DCHECK_RUN_ON(&test_controller_thread_checker_);
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);
udp_transport_->SetRemoteAddress(remote_addr);
SendData(packet, rtc::Optional<size_t>());
packet_sender_.reset(new PacketSender(this, config_file_path_));
packet_sender_->StartSending();
rtc::CritScope scoped_lock(&local_test_done_lock_);
local_test_done_ = false;
remote_test_done_ = false;
break;
}
case NetworkTesterPacket::TEST_START: {
packet_sender_.reset(new PacketSender(this, config_file_path_));
packet_sender_->StartSending();
rtc::CritScope scoped_lock(&local_test_done_lock_);
local_test_done_ = false;
remote_test_done_ = false;
break;
}
case NetworkTesterPacket::TEST_DATA: {
packet.set_arrival_timestamp(packet_time.timestamp);
packet.set_packet_size(len);
packet_logger_.LogPacket(packet);
break;
}
case NetworkTesterPacket::TEST_DONE: {
remote_test_done_ = true;
break;
}
default: { RTC_NOTREACHED(); }
}
}
} // namespace webrtc

View File

@ -0,0 +1,81 @@
/*
* 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 WEBRTC_RTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_
#define WEBRTC_RTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_
#include <array>
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include "webrtc/p2p/base/basicpacketsocketfactory.h"
#include "webrtc/p2p/base/udptransport.h"
#include "webrtc/rtc_base/constructormagic.h"
#include "webrtc/rtc_base/ignore_wundef.h"
#include "webrtc/rtc_tools/network_tester/packet_logger.h"
#include "webrtc/rtc_tools/network_tester/packet_sender.h"
#ifdef WEBRTC_NETWORK_TESTER_PROTO
RTC_PUSH_IGNORING_WUNDEF()
#include "webrtc/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);
void Run();
void SendConnectTo(const std::string& hostname, int port);
void SendData(const NetworkTesterPacket& packet,
rtc::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 rtc::PacketTime& packet_time);
rtc::ThreadChecker test_controller_thread_checker_;
rtc::SequencedTaskChecker packet_sender_checker_;
rtc::BasicPacketSocketFactory socket_factory_;
const std::string config_file_path_;
PacketLogger packet_logger_;
rtc::CriticalSection local_test_done_lock_;
bool local_test_done_ RTC_GUARDED_BY(local_test_done_lock_);
bool remote_test_done_;
std::array<char, kEthernetMtu> send_data_;
std::unique_ptr<cricket::UdpTransport> udp_transport_;
std::unique_ptr<PacketSender> packet_sender_;
RTC_DISALLOW_COPY_AND_ASSIGN(TestController);
};
} // namespace webrtc
#endif // WEBRTC_RTC_TOOLS_NETWORK_TESTER_TEST_CONTROLLER_H_