1 /*
2  *  Copyright 2013 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 PC_TEST_FAKE_DATA_CHANNEL_PROVIDER_H_
12 #define PC_TEST_FAKE_DATA_CHANNEL_PROVIDER_H_
13 
14 #include <set>
15 
16 #include "pc/sctp_data_channel.h"
17 #include "rtc_base/checks.h"
18 
19 class FakeDataChannelProvider
20     : public webrtc::SctpDataChannelProviderInterface {
21  public:
FakeDataChannelProvider()22   FakeDataChannelProvider()
23       : send_blocked_(false),
24         transport_available_(false),
25         ready_to_send_(false),
26         transport_error_(false) {}
~FakeDataChannelProvider()27   virtual ~FakeDataChannelProvider() {}
28 
SendData(const cricket::SendDataParams & params,const rtc::CopyOnWriteBuffer & payload,cricket::SendDataResult * result)29   bool SendData(const cricket::SendDataParams& params,
30                 const rtc::CopyOnWriteBuffer& payload,
31                 cricket::SendDataResult* result) override {
32     RTC_CHECK(ready_to_send_);
33     RTC_CHECK(transport_available_);
34     if (send_blocked_) {
35       *result = cricket::SDR_BLOCK;
36       return false;
37     }
38 
39     if (transport_error_ || payload.size() == 0) {
40       *result = cricket::SDR_ERROR;
41       return false;
42     }
43 
44     last_send_data_params_ = params;
45     return true;
46   }
47 
ConnectDataChannel(webrtc::SctpDataChannel * data_channel)48   bool ConnectDataChannel(webrtc::SctpDataChannel* data_channel) override {
49     RTC_CHECK(connected_channels_.find(data_channel) ==
50               connected_channels_.end());
51     if (!transport_available_) {
52       return false;
53     }
54     RTC_LOG(LS_INFO) << "DataChannel connected " << data_channel;
55     connected_channels_.insert(data_channel);
56     return true;
57   }
58 
DisconnectDataChannel(webrtc::SctpDataChannel * data_channel)59   void DisconnectDataChannel(webrtc::SctpDataChannel* data_channel) override {
60     RTC_CHECK(connected_channels_.find(data_channel) !=
61               connected_channels_.end());
62     RTC_LOG(LS_INFO) << "DataChannel disconnected " << data_channel;
63     connected_channels_.erase(data_channel);
64   }
65 
AddSctpDataStream(int sid)66   void AddSctpDataStream(int sid) override {
67     RTC_CHECK(sid >= 0);
68     if (!transport_available_) {
69       return;
70     }
71     send_ssrcs_.insert(sid);
72     recv_ssrcs_.insert(sid);
73   }
74 
RemoveSctpDataStream(int sid)75   void RemoveSctpDataStream(int sid) override {
76     RTC_CHECK(sid >= 0);
77     send_ssrcs_.erase(sid);
78     recv_ssrcs_.erase(sid);
79     // Unlike the real SCTP transport, act like the closing procedure finished
80     // instantly, doing the same snapshot thing as below.
81     for (webrtc::SctpDataChannel* ch : std::set<webrtc::SctpDataChannel*>(
82              connected_channels_.begin(), connected_channels_.end())) {
83       if (connected_channels_.count(ch)) {
84         ch->OnClosingProcedureComplete(sid);
85       }
86     }
87   }
88 
ReadyToSendData()89   bool ReadyToSendData() const override { return ready_to_send_; }
90 
91   // Set true to emulate the SCTP stream being blocked by congestion control.
set_send_blocked(bool blocked)92   void set_send_blocked(bool blocked) {
93     send_blocked_ = blocked;
94     if (!blocked) {
95       // Take a snapshot of the connected channels and check to see whether
96       // each value is still in connected_channels_ before calling
97       // OnTransportReady().  This avoids problems where the set gets modified
98       // in response to OnTransportReady().
99       for (webrtc::SctpDataChannel* ch : std::set<webrtc::SctpDataChannel*>(
100                connected_channels_.begin(), connected_channels_.end())) {
101         if (connected_channels_.count(ch)) {
102           ch->OnTransportReady(true);
103         }
104       }
105     }
106   }
107 
108   // Set true to emulate the transport channel creation, e.g. after
109   // setLocalDescription/setRemoteDescription called with data content.
set_transport_available(bool available)110   void set_transport_available(bool available) {
111     transport_available_ = available;
112   }
113 
114   // Set true to emulate the transport ReadyToSendData signal when the transport
115   // becomes writable for the first time.
set_ready_to_send(bool ready)116   void set_ready_to_send(bool ready) {
117     RTC_CHECK(transport_available_);
118     ready_to_send_ = ready;
119     if (ready) {
120       std::set<webrtc::SctpDataChannel*>::iterator it;
121       for (it = connected_channels_.begin(); it != connected_channels_.end();
122            ++it) {
123         (*it)->OnTransportReady(true);
124       }
125     }
126   }
127 
set_transport_error()128   void set_transport_error() { transport_error_ = true; }
129 
last_send_data_params()130   cricket::SendDataParams last_send_data_params() const {
131     return last_send_data_params_;
132   }
133 
IsConnected(webrtc::SctpDataChannel * data_channel)134   bool IsConnected(webrtc::SctpDataChannel* data_channel) const {
135     return connected_channels_.find(data_channel) != connected_channels_.end();
136   }
137 
IsSendStreamAdded(uint32_t stream)138   bool IsSendStreamAdded(uint32_t stream) const {
139     return send_ssrcs_.find(stream) != send_ssrcs_.end();
140   }
141 
IsRecvStreamAdded(uint32_t stream)142   bool IsRecvStreamAdded(uint32_t stream) const {
143     return recv_ssrcs_.find(stream) != recv_ssrcs_.end();
144   }
145 
146  private:
147   cricket::SendDataParams last_send_data_params_;
148   bool send_blocked_;
149   bool transport_available_;
150   bool ready_to_send_;
151   bool transport_error_;
152   std::set<webrtc::SctpDataChannel*> connected_channels_;
153   std::set<uint32_t> send_ssrcs_;
154   std::set<uint32_t> recv_ssrcs_;
155 };
156 #endif  // PC_TEST_FAKE_DATA_CHANNEL_PROVIDER_H_
157