xref: /aosp_15_r20/external/webrtc/p2p/base/fake_packet_transport.h (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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