Using EmulatedEndpoint in Scenario tests.

Bug: webrtc:9883
Change-Id: I7d1dc9d8efbdddc14e1fbe08d7b6a71c4bbe24ae
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/166341
Commit-Queue: Sebastian Jansson <srte@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#30300}
diff --git a/api/test/network_emulation/network_emulation_interfaces.h b/api/test/network_emulation/network_emulation_interfaces.h
index 5d75bf3..0986df4 100644
--- a/api/test/network_emulation/network_emulation_interfaces.h
+++ b/api/test/network_emulation/network_emulation_interfaces.h
@@ -99,7 +99,8 @@
   // on destination endpoint.
   virtual void SendPacket(const rtc::SocketAddress& from,
                           const rtc::SocketAddress& to,
-                          rtc::CopyOnWriteBuffer packet_data) = 0;
+                          rtc::CopyOnWriteBuffer packet_data,
+                          uint16_t application_overhead = 0) = 0;
 
   // Binds receiver to this endpoint to send and receive data.
   // |desired_port| is a port that should be used. If it is equal to 0,
diff --git a/test/network/network_emulation.cc b/test/network/network_emulation.cc
index f21b0eb..a0ac5ae 100644
--- a/test/network/network_emulation.cc
+++ b/test/network/network_emulation.cc
@@ -203,10 +203,11 @@
 
 void EmulatedEndpointImpl::SendPacket(const rtc::SocketAddress& from,
                                       const rtc::SocketAddress& to,
-                                      rtc::CopyOnWriteBuffer packet_data) {
+                                      rtc::CopyOnWriteBuffer packet_data,
+                                      uint16_t application_overhead) {
   RTC_CHECK(from.ipaddr() == peer_local_addr_);
   EmulatedIpPacket packet(from, to, std::move(packet_data),
-                          clock_->CurrentTime());
+                          clock_->CurrentTime(), application_overhead);
   task_queue_->PostTask([this, packet = std::move(packet)]() mutable {
     RTC_DCHECK_RUN_ON(task_queue_);
     Timestamp current_time = clock_->CurrentTime();
diff --git a/test/network/network_emulation.h b/test/network/network_emulation.h
index b5e8164..bb5319f 100644
--- a/test/network/network_emulation.h
+++ b/test/network/network_emulation.h
@@ -140,7 +140,8 @@
 
   void SendPacket(const rtc::SocketAddress& from,
                   const rtc::SocketAddress& to,
-                  rtc::CopyOnWriteBuffer packet_data) override;
+                  rtc::CopyOnWriteBuffer packet_data,
+                  uint16_t application_overhead = 0) override;
 
   absl::optional<uint16_t> BindReceiver(
       uint16_t desired_port,
diff --git a/test/scenario/call_client.cc b/test/scenario/call_client.cc
index 61612c5..fb888df6 100644
--- a/test/scenario/call_client.cc
+++ b/test/scenario/call_client.cc
@@ -318,6 +318,17 @@
   task_queue_.SendTask(std::move(task), RTC_FROM_HERE);
 }
 
+int16_t CallClient::Bind(EmulatedEndpoint* endpoint) {
+  uint16_t port = endpoint->BindReceiver(0, this).value();
+  endpoints_.push_back({endpoint, port});
+  return port;
+}
+
+void CallClient::UnBind() {
+  for (auto ep_port : endpoints_)
+    ep_port.first->UnbindReceiver(ep_port.second);
+}
+
 CallClientPair::~CallClientPair() = default;
 
 }  // namespace test
diff --git a/test/scenario/call_client.h b/test/scenario/call_client.h
index a4c04af..1fbe256 100644
--- a/test/scenario/call_client.h
+++ b/test/scenario/call_client.h
@@ -130,6 +130,8 @@
   uint32_t GetNextRtxSsrc();
   void AddExtensions(std::vector<RtpExtension> extensions);
   void SendTask(std::function<void()> task);
+  int16_t Bind(EmulatedEndpoint* endpoint);
+  void UnBind();
 
   TimeController* const time_controller_;
   Clock* clock_;
@@ -140,6 +142,7 @@
   std::unique_ptr<Call> call_;
   std::unique_ptr<NetworkNodeTransport> transport_;
   std::unique_ptr<RtpHeaderParser> const header_parser_;
+  std::vector<std::pair<EmulatedEndpoint*, uint16_t>> endpoints_;
 
   int next_video_ssrc_index_ = 0;
   int next_video_local_ssrc_index_ = 0;
diff --git a/test/scenario/network_node.cc b/test/scenario/network_node.cc
index c430b87..4855520 100644
--- a/test/scenario/network_node.cc
+++ b/test/scenario/network_node.cc
@@ -85,48 +85,42 @@
   sent_packet.info.packet_type = rtc::PacketType::kData;
   sender_call_->OnSentPacket(sent_packet);
 
-  Timestamp send_time = Timestamp::ms(send_time_ms);
   rtc::CritScope crit(&crit_sect_);
-  if (!send_net_)
+  if (!endpoint_)
     return false;
   rtc::CopyOnWriteBuffer buffer(packet, length);
-  send_net_->OnPacketReceived(
-      EmulatedIpPacket(local_address_, receiver_address_, buffer, send_time,
-                       packet_overhead_.bytes()));
+  endpoint_->SendPacket(local_address_, remote_address_, buffer,
+                        packet_overhead_.bytes());
   return true;
 }
 
 bool NetworkNodeTransport::SendRtcp(const uint8_t* packet, size_t length) {
   rtc::CopyOnWriteBuffer buffer(packet, length);
-  Timestamp send_time = sender_clock_->CurrentTime();
   rtc::CritScope crit(&crit_sect_);
-  if (!send_net_)
+  if (!endpoint_)
     return false;
-  send_net_->OnPacketReceived(
-      EmulatedIpPacket(local_address_, receiver_address_, buffer, send_time,
-                       packet_overhead_.bytes()));
+  endpoint_->SendPacket(local_address_, remote_address_, buffer,
+                        packet_overhead_.bytes());
   return true;
 }
 
-void NetworkNodeTransport::Connect(EmulatedNetworkNode* send_node,
-                                   const rtc::IPAddress& receiver_ip,
+void NetworkNodeTransport::Connect(EmulatedEndpoint* endpoint,
+                                   const rtc::SocketAddress& receiver_address,
                                    DataSize packet_overhead) {
   rtc::NetworkRoute route;
   route.connected = true;
-  route.local_network_id =
-      static_cast<uint16_t>(receiver_ip.v4AddressAsHostOrderInteger());
-  route.remote_network_id =
-      static_cast<uint16_t>(receiver_ip.v4AddressAsHostOrderInteger());
+  // We assume that the address will be unique in the lower bytes.
+  route.local_network_id = static_cast<uint16_t>(
+      receiver_address.ipaddr().v4AddressAsHostOrderInteger());
+  route.remote_network_id = static_cast<uint16_t>(
+      receiver_address.ipaddr().v4AddressAsHostOrderInteger());
   {
-    // Only IPv4 address is supported. We don't use full range of IPs in
-    // scenario framework and also we need a simple way to convert IP into
-    // network_id to signal network route.
-    RTC_CHECK_EQ(receiver_ip.family(), AF_INET);
-    RTC_CHECK_LE(receiver_ip.v4AddressAsHostOrderInteger(),
-                 std::numeric_limits<uint16_t>::max());
+    // Only IPv4 address is supported.
+    RTC_CHECK_EQ(receiver_address.family(), AF_INET);
     rtc::CritScope crit(&crit_sect_);
-    send_net_ = send_node;
-    receiver_address_ = rtc::SocketAddress(receiver_ip, 0);
+    endpoint_ = endpoint;
+    local_address_ = rtc::SocketAddress(endpoint_->GetPeerLocalAddress(), 0);
+    remote_address_ = receiver_address;
     packet_overhead_ = packet_overhead;
     current_network_route_ = route;
   }
@@ -141,7 +135,7 @@
   sender_call_->GetTransportControllerSend()->OnNetworkRouteChanged(
       kDummyTransportName, current_network_route_);
   current_network_route_ = {};
-  send_net_ = nullptr;
+  endpoint_ = nullptr;
 }
 
 }  // namespace test
diff --git a/test/scenario/network_node.h b/test/scenario/network_node.h
index 80f8a99..b3d093b 100644
--- a/test/scenario/network_node.h
+++ b/test/scenario/network_node.h
@@ -59,8 +59,8 @@
                const PacketOptions& options) override;
   bool SendRtcp(const uint8_t* packet, size_t length) override;
 
-  void Connect(EmulatedNetworkNode* send_node,
-               const rtc::IPAddress& receiver_ip,
+  void Connect(EmulatedEndpoint* endpoint,
+               const rtc::SocketAddress& receiver_address,
                DataSize packet_overhead);
   void Disconnect();
 
@@ -73,10 +73,9 @@
   rtc::CriticalSection crit_sect_;
   Clock* const sender_clock_;
   Call* const sender_call_;
-  // Store local address here for consistency with receiver address.
-  const rtc::SocketAddress local_address_;
-  EmulatedNetworkNode* send_net_ RTC_GUARDED_BY(crit_sect_) = nullptr;
-  rtc::SocketAddress receiver_address_ RTC_GUARDED_BY(crit_sect_);
+  EmulatedEndpoint* endpoint_ RTC_GUARDED_BY(crit_sect_) = nullptr;
+  rtc::SocketAddress local_address_ RTC_GUARDED_BY(crit_sect_);
+  rtc::SocketAddress remote_address_ RTC_GUARDED_BY(crit_sect_);
   DataSize packet_overhead_ RTC_GUARDED_BY(crit_sect_) = DataSize::Zero();
   rtc::NetworkRoute current_network_route_ RTC_GUARDED_BY(crit_sect_);
 };
diff --git a/test/scenario/scenario.cc b/test/scenario/scenario.cc
index 9d27e6a..0c5e381 100644
--- a/test/scenario/scenario.cc
+++ b/test/scenario/scenario.cc
@@ -75,10 +75,10 @@
     bool real_time)
     : log_writer_factory_(std::move(log_writer_factory)),
       time_controller_(CreateTimeController(real_time)),
+      network_manager_(time_controller_.get()),
       clock_(time_controller_->GetClock()),
       audio_decoder_factory_(CreateBuiltinAudioDecoderFactory()),
       audio_encoder_factory_(CreateBuiltinAudioEncoderFactory()),
-      network_manager_(time_controller_.get()),
       task_queue_(time_controller_->GetTaskQueueFactory()->CreateTaskQueue(
           "Scenario",
           TaskQueueFactory::Priority::NORMAL)) {}
@@ -86,8 +86,10 @@
 Scenario::~Scenario() {
   if (start_time_.IsFinite())
     Stop();
-  for (auto& call_client : clients_)
+  for (auto& call_client : clients_) {
     call_client->transport_->Disconnect();
+    call_client->UnBind();
+  }
 }
 
 ColumnPrinter Scenario::TimePrinter() {
@@ -165,9 +167,10 @@
 void Scenario::ChangeRoute(std::pair<CallClient*, CallClient*> clients,
                            std::vector<EmulatedNetworkNode*> over_nodes,
                            DataSize overhead) {
-  rtc::IPAddress route_ip(next_route_id_++);
-  EmulatedNetworkNode::CreateRoute(route_ip, over_nodes, clients.second);
-  clients.first->transport_->Connect(over_nodes.front(), route_ip, overhead);
+  EmulatedRoute* route = network_manager_.CreateRoute(over_nodes);
+  uint16_t port = clients.second->Bind(route->to);
+  auto addr = rtc::SocketAddress(route->to->GetPeerLocalAddress(), port);
+  clients.first->transport_->Connect(route->from, addr, overhead);
 }
 
 EmulatedNetworkNode* Scenario::CreateSimulationNode(
diff --git a/test/scenario/scenario.h b/test/scenario/scenario.h
index a4dc471..a5803bf 100644
--- a/test/scenario/scenario.h
+++ b/test/scenario/scenario.h
@@ -162,6 +162,7 @@
 
   const std::unique_ptr<LogWriterFactoryInterface> log_writer_factory_;
   std::unique_ptr<TimeController> time_controller_;
+  NetworkEmulationManagerImpl network_manager_;
   Clock* clock_;
 
   std::vector<std::unique_ptr<CallClient>> clients_;
@@ -171,12 +172,10 @@
   std::vector<std::unique_ptr<SimulationNode>> simulation_nodes_;
   std::vector<std::unique_ptr<StatesPrinter>> printers_;
 
-  int64_t next_route_id_ = 40000;
   rtc::scoped_refptr<AudioDecoderFactory> audio_decoder_factory_;
   rtc::scoped_refptr<AudioEncoderFactory> audio_encoder_factory_;
 
   Timestamp start_time_ = Timestamp::PlusInfinity();
-  NetworkEmulationManagerImpl network_manager_;
   // Defined last so it's destroyed first.
   rtc::TaskQueue task_queue_;
 };