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