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