blob: aa576dcf538a4b3fcd76e43cdd83f025d8ecd05f [file] [log] [blame]
Sebastian Jansson98b07e92018-09-27 13:47:01 +02001/*
2 * Copyright 2018 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10#include "test/scenario/network_node.h"
11
12#include <algorithm>
13#include <vector>
14
Mirko Bonadei317a1f02019-09-17 17:06:18 +020015#include <memory>
Sebastian Janssonf52d3ed2020-02-28 16:22:09 +010016#include "rtc_base/net_helper.h"
Yves Gerey2e00abc2018-10-05 15:39:24 +020017#include "rtc_base/numerics/safe_minmax.h"
18
Sebastian Jansson98b07e92018-09-27 13:47:01 +020019namespace webrtc {
20namespace test {
21namespace {
Sebastian Jansson4124dab2019-04-01 14:33:53 +020022constexpr char kDummyTransportName[] = "dummy";
Sebastian Janssonef86d142019-04-15 14:42:42 +020023SimulatedNetwork::Config CreateSimulationConfig(
24 NetworkSimulationConfig config) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020025 SimulatedNetwork::Config sim_config;
Sebastian Janssonef86d142019-04-15 14:42:42 +020026 sim_config.link_capacity_kbps = config.bandwidth.kbps_or(0);
27 sim_config.loss_percent = config.loss_rate * 100;
28 sim_config.queue_delay_ms = config.delay.ms();
29 sim_config.delay_standard_deviation_ms = config.delay_std_dev.ms();
Sebastian Jansson8c8feb92019-01-29 15:59:17 +010030 sim_config.packet_overhead = config.packet_overhead.bytes<int>();
Sebastian Jansson2b08e312019-02-25 10:24:46 +010031 sim_config.codel_active_queue_management =
Sebastian Janssonef86d142019-04-15 14:42:42 +020032 config.codel_active_queue_management;
Sebastian Jansson24c678f2019-10-14 15:07:58 +020033 sim_config.queue_length_packets =
34 config.packet_queue_length_limit.value_or(0);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020035 return sim_config;
36}
37} // namespace
38
Sebastian Janssona4c22b92019-04-15 21:10:00 +020039SimulationNode::SimulationNode(NetworkSimulationConfig config,
40 SimulatedNetwork* behavior,
41 EmulatedNetworkNode* network_node)
42 : config_(config), simulation_(behavior), network_node_(network_node) {}
Sebastian Jansson98b07e92018-09-27 13:47:01 +020043
Sebastian Janssona4c22b92019-04-15 21:10:00 +020044std::unique_ptr<SimulatedNetwork> SimulationNode::CreateBehavior(
Sebastian Janssonef86d142019-04-15 14:42:42 +020045 NetworkSimulationConfig config) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020046 SimulatedNetwork::Config sim_config = CreateSimulationConfig(config);
Mirko Bonadei317a1f02019-09-17 17:06:18 +020047 return std::make_unique<SimulatedNetwork>(sim_config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020048}
49
50void SimulationNode::UpdateConfig(
Sebastian Janssonef86d142019-04-15 14:42:42 +020051 std::function<void(NetworkSimulationConfig*)> modifier) {
Sebastian Jansson98b07e92018-09-27 13:47:01 +020052 modifier(&config_);
53 SimulatedNetwork::Config sim_config = CreateSimulationConfig(config_);
Sebastian Janssona4c22b92019-04-15 21:10:00 +020054 simulation_->SetConfig(sim_config);
Sebastian Jansson98b07e92018-09-27 13:47:01 +020055}
56
57void SimulationNode::PauseTransmissionUntil(Timestamp until) {
Sebastian Janssona4c22b92019-04-15 21:10:00 +020058 simulation_->PauseTransmissionUntil(until.us());
Sebastian Jansson98b07e92018-09-27 13:47:01 +020059}
60
61ColumnPrinter SimulationNode::ConfigPrinter() const {
Sebastian Janssonef86d142019-04-15 14:42:42 +020062 return ColumnPrinter::Lambda(
63 "propagation_delay capacity loss_rate",
64 [this](rtc::SimpleStringBuilder& sb) {
65 sb.AppendFormat("%.3lf %.0lf %.2lf", config_.delay.seconds<double>(),
66 config_.bandwidth.bps() / 8.0, config_.loss_rate);
67 });
Sebastian Jansson98b07e92018-09-27 13:47:01 +020068}
69
Sebastian Janssonaa01f272019-01-30 11:28:59 +010070NetworkNodeTransport::NetworkNodeTransport(Clock* sender_clock,
Sebastian Jansson800e1212018-10-22 11:49:03 +020071 Call* sender_call)
72 : sender_clock_(sender_clock), sender_call_(sender_call) {}
Sebastian Jansson98b07e92018-09-27 13:47:01 +020073
74NetworkNodeTransport::~NetworkNodeTransport() = default;
75
76bool NetworkNodeTransport::SendRtp(const uint8_t* packet,
77 size_t length,
78 const PacketOptions& options) {
Sebastian Jansson800e1212018-10-22 11:49:03 +020079 int64_t send_time_ms = sender_clock_->TimeInMilliseconds();
Sebastian Jansson156d11d2018-09-28 17:21:34 +020080 rtc::SentPacket sent_packet;
81 sent_packet.packet_id = options.packet_id;
Sebastian Jansson03789972018-10-09 18:27:57 +020082 sent_packet.info.included_in_feedback = options.included_in_feedback;
83 sent_packet.info.included_in_allocation = options.included_in_allocation;
Sebastian Jansson156d11d2018-09-28 17:21:34 +020084 sent_packet.send_time_ms = send_time_ms;
85 sent_packet.info.packet_size_bytes = length;
86 sent_packet.info.packet_type = rtc::PacketType::kData;
Sebastian Jansson800e1212018-10-22 11:49:03 +020087 sender_call_->OnSentPacket(sent_packet);
Sebastian Jansson156d11d2018-09-28 17:21:34 +020088
Sebastian Jansson800e1212018-10-22 11:49:03 +020089 rtc::CritScope crit(&crit_sect_);
Sebastian Jansson77bd3852020-01-17 13:05:54 +010090 if (!endpoint_)
Sebastian Jansson800e1212018-10-22 11:49:03 +020091 return false;
Sebastian Janssonc9f42ad2020-01-17 11:47:35 +010092 rtc::CopyOnWriteBuffer buffer(packet, length);
Sebastian Jansson77bd3852020-01-17 13:05:54 +010093 endpoint_->SendPacket(local_address_, remote_address_, buffer,
94 packet_overhead_.bytes());
Sebastian Janssonf65309c2018-12-20 10:26:00 +010095 return true;
Sebastian Jansson98b07e92018-09-27 13:47:01 +020096}
97
98bool NetworkNodeTransport::SendRtcp(const uint8_t* packet, size_t length) {
99 rtc::CopyOnWriteBuffer buffer(packet, length);
Sebastian Jansson800e1212018-10-22 11:49:03 +0200100 rtc::CritScope crit(&crit_sect_);
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100101 if (!endpoint_)
Sebastian Jansson800e1212018-10-22 11:49:03 +0200102 return false;
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100103 endpoint_->SendPacket(local_address_, remote_address_, buffer,
104 packet_overhead_.bytes());
Sebastian Janssonf65309c2018-12-20 10:26:00 +0100105 return true;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200106}
107
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100108void NetworkNodeTransport::Connect(EmulatedEndpoint* endpoint,
109 const rtc::SocketAddress& receiver_address,
Sebastian Jansson800e1212018-10-22 11:49:03 +0200110 DataSize packet_overhead) {
Sebastian Jansson800e1212018-10-22 11:49:03 +0200111 rtc::NetworkRoute route;
112 route.connected = true;
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100113 // We assume that the address will be unique in the lower bytes.
Jonas Oreland71fda362020-03-20 16:11:56 +0100114 route.local = rtc::RouteEndpoint::CreateWithNetworkId(static_cast<uint16_t>(
115 receiver_address.ipaddr().v4AddressAsHostOrderInteger()));
116 route.remote = rtc::RouteEndpoint::CreateWithNetworkId(static_cast<uint16_t>(
117 receiver_address.ipaddr().v4AddressAsHostOrderInteger()));
Sebastian Janssonf52d3ed2020-02-28 16:22:09 +0100118 route.packet_overhead = packet_overhead.bytes() +
119 receiver_address.ipaddr().overhead() +
120 cricket::kUdpHeaderSize;
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200121 {
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100122 // Only IPv4 address is supported.
123 RTC_CHECK_EQ(receiver_address.family(), AF_INET);
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200124 rtc::CritScope crit(&crit_sect_);
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100125 endpoint_ = endpoint;
126 local_address_ = rtc::SocketAddress(endpoint_->GetPeerLocalAddress(), 0);
127 remote_address_ = receiver_address;
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200128 packet_overhead_ = packet_overhead;
129 current_network_route_ = route;
130 }
131
Sebastian Jansson800e1212018-10-22 11:49:03 +0200132 sender_call_->GetTransportControllerSend()->OnNetworkRouteChanged(
Sebastian Jansson4124dab2019-04-01 14:33:53 +0200133 kDummyTransportName, route);
134}
135
136void NetworkNodeTransport::Disconnect() {
137 rtc::CritScope crit(&crit_sect_);
138 current_network_route_.connected = false;
139 sender_call_->GetTransportControllerSend()->OnNetworkRouteChanged(
140 kDummyTransportName, current_network_route_);
141 current_network_route_ = {};
Sebastian Jansson77bd3852020-01-17 13:05:54 +0100142 endpoint_ = nullptr;
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200143}
144
Sebastian Jansson98b07e92018-09-27 13:47:01 +0200145} // namespace test
146} // namespace webrtc