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