| // Copyright (c) 2018 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "net/third_party/quiche/src/quic/quartc/simulated_packet_transport.h" | 
 |  | 
 | #include <utility> | 
 |  | 
 | #include "net/third_party/quiche/src/quic/platform/api/quic_str_cat.h" | 
 |  | 
 | namespace quic { | 
 | namespace simulator { | 
 |  | 
 | SimulatedQuartcPacketTransport::SimulatedQuartcPacketTransport( | 
 |     Simulator* simulator, | 
 |     const std::string& name, | 
 |     const std::string& peer_name, | 
 |     QuicByteCount queue_capacity) | 
 |     : Endpoint(simulator, name), | 
 |       peer_name_(peer_name), | 
 |       egress_queue_(simulator, | 
 |                     QuicStringPrintf("%s (TX Queue)", name.c_str()), | 
 |                     queue_capacity) { | 
 |   egress_queue_.set_listener_interface(this); | 
 | } | 
 |  | 
 | int SimulatedQuartcPacketTransport::Write(const char* buffer, | 
 |                                           size_t buf_len, | 
 |                                           const PacketInfo& info) { | 
 |   if (!writable_) { | 
 |     return 0; | 
 |   } | 
 |   if (egress_queue_.bytes_queued() + buf_len > egress_queue_.capacity()) { | 
 |     return 0; | 
 |   } | 
 |  | 
 |   last_packet_number_ = info.packet_number; | 
 |  | 
 |   auto packet = std::make_unique<Packet>(); | 
 |   packet->contents = std::string(buffer, buf_len); | 
 |   packet->size = buf_len; | 
 |   packet->tx_timestamp = clock_->Now(); | 
 |   packet->source = name(); | 
 |   packet->destination = peer_name_; | 
 |  | 
 |   egress_queue_.AcceptPacket(std::move(packet)); | 
 |   return buf_len; | 
 | } | 
 |  | 
 | void SimulatedQuartcPacketTransport::SetDelegate(Delegate* delegate) { | 
 |   delegate_ = delegate; | 
 |   Schedule(clock_->Now()); | 
 | } | 
 |  | 
 | UnconstrainedPortInterface* SimulatedQuartcPacketTransport::GetRxPort() { | 
 |   return this; | 
 | } | 
 |  | 
 | void SimulatedQuartcPacketTransport::SetTxPort(ConstrainedPortInterface* port) { | 
 |   egress_queue_.set_tx_port(port); | 
 |   Schedule(clock_->Now()); | 
 | } | 
 |  | 
 | void SimulatedQuartcPacketTransport::AcceptPacket( | 
 |     std::unique_ptr<Packet> packet) { | 
 |   // Simulated switches broadcast packets to all ports if the cannot determine | 
 |   // the recipient, so we need to drop packets that aren't intended for us. | 
 |   if (packet->destination != name()) { | 
 |     return; | 
 |   } | 
 |  | 
 |   if (delegate_) { | 
 |     delegate_->OnTransportReceived(packet->contents.data(), packet->size); | 
 |   } | 
 | } | 
 |  | 
 | void SimulatedQuartcPacketTransport::OnPacketDequeued() { | 
 |   if (delegate_ && writable_) { | 
 |     delegate_->OnTransportCanWrite(); | 
 |   } | 
 | } | 
 |  | 
 | void SimulatedQuartcPacketTransport::Act() { | 
 |   if (delegate_ && writable_) { | 
 |     delegate_->OnTransportCanWrite(); | 
 |   } | 
 | } | 
 |  | 
 | void SimulatedQuartcPacketTransport::SetWritable(bool writable) { | 
 |   writable_ = writable; | 
 |   if (writable_) { | 
 |     // May need to call |Delegate::OnTransportCanWrite|. | 
 |     Schedule(clock_->Now()); | 
 |   } | 
 | } | 
 |  | 
 | }  // namespace simulator | 
 | }  // namespace quic |