1 /* 2 * Copyright 2017 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 11 #ifndef P2P_BASE_FAKE_PACKET_TRANSPORT_H_ 12 #define P2P_BASE_FAKE_PACKET_TRANSPORT_H_ 13 14 #include <map> 15 #include <string> 16 17 #include "p2p/base/packet_transport_internal.h" 18 #include "rtc_base/copy_on_write_buffer.h" 19 20 namespace rtc { 21 22 // Used to simulate a packet-based transport. 23 class FakePacketTransport : public PacketTransportInternal { 24 public: FakePacketTransport(const std::string & transport_name)25 explicit FakePacketTransport(const std::string& transport_name) 26 : transport_name_(transport_name) {} ~FakePacketTransport()27 ~FakePacketTransport() override { 28 if (dest_ && dest_->dest_ == this) { 29 dest_->dest_ = nullptr; 30 } 31 } 32 33 // SetWritable, SetReceiving and SetDestination are the main methods that can 34 // be used for testing, to simulate connectivity or lack thereof. SetWritable(bool writable)35 void SetWritable(bool writable) { set_writable(writable); } SetReceiving(bool receiving)36 void SetReceiving(bool receiving) { set_receiving(receiving); } 37 38 // Simulates the two transports connecting to each other. 39 // If `asymmetric` is true this method only affects this FakePacketTransport. 40 // If false, it affects `dest` as well. SetDestination(FakePacketTransport * dest,bool asymmetric)41 void SetDestination(FakePacketTransport* dest, bool asymmetric) { 42 if (dest) { 43 dest_ = dest; 44 set_writable(true); 45 if (!asymmetric) { 46 dest->SetDestination(this, true); 47 } 48 } else { 49 // Simulates loss of connectivity, by asymmetrically forgetting dest_. 50 dest_ = nullptr; 51 set_writable(false); 52 } 53 } 54 55 // Fake PacketTransportInternal implementation. transport_name()56 const std::string& transport_name() const override { return transport_name_; } writable()57 bool writable() const override { return writable_; } receiving()58 bool receiving() const override { return receiving_; } SendPacket(const char * data,size_t len,const PacketOptions & options,int flags)59 int SendPacket(const char* data, 60 size_t len, 61 const PacketOptions& options, 62 int flags) override { 63 if (!dest_) { 64 return -1; 65 } 66 CopyOnWriteBuffer packet(data, len); 67 SendPacketInternal(packet); 68 69 SentPacket sent_packet(options.packet_id, TimeMillis()); 70 SignalSentPacket(this, sent_packet); 71 return static_cast<int>(len); 72 } 73 SetOption(Socket::Option opt,int value)74 int SetOption(Socket::Option opt, int value) override { 75 options_[opt] = value; 76 return 0; 77 } 78 GetOption(Socket::Option opt,int * value)79 bool GetOption(Socket::Option opt, int* value) override { 80 auto it = options_.find(opt); 81 if (it == options_.end()) { 82 return false; 83 } 84 *value = it->second; 85 return true; 86 } 87 GetError()88 int GetError() override { return error_; } SetError(int error)89 void SetError(int error) { error_ = error; } 90 last_sent_packet()91 const CopyOnWriteBuffer* last_sent_packet() { return &last_sent_packet_; } 92 network_route()93 absl::optional<NetworkRoute> network_route() const override { 94 return network_route_; 95 } SetNetworkRoute(absl::optional<NetworkRoute> network_route)96 void SetNetworkRoute(absl::optional<NetworkRoute> network_route) { 97 network_route_ = network_route; 98 SignalNetworkRouteChanged(network_route); 99 } 100 101 private: set_writable(bool writable)102 void set_writable(bool writable) { 103 if (writable_ == writable) { 104 return; 105 } 106 writable_ = writable; 107 if (writable_) { 108 SignalReadyToSend(this); 109 } 110 SignalWritableState(this); 111 } 112 set_receiving(bool receiving)113 void set_receiving(bool receiving) { 114 if (receiving_ == receiving) { 115 return; 116 } 117 receiving_ = receiving; 118 SignalReceivingState(this); 119 } 120 SendPacketInternal(const CopyOnWriteBuffer & packet)121 void SendPacketInternal(const CopyOnWriteBuffer& packet) { 122 last_sent_packet_ = packet; 123 if (dest_) { 124 dest_->SignalReadPacket(dest_, packet.data<char>(), packet.size(), 125 TimeMicros(), 0); 126 } 127 } 128 129 CopyOnWriteBuffer last_sent_packet_; 130 std::string transport_name_; 131 FakePacketTransport* dest_ = nullptr; 132 bool writable_ = false; 133 bool receiving_ = false; 134 135 std::map<Socket::Option, int> options_; 136 int error_ = 0; 137 138 absl::optional<NetworkRoute> network_route_; 139 }; 140 141 } // namespace rtc 142 143 #endif // P2P_BASE_FAKE_PACKET_TRANSPORT_H_ 144