| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include "webrtc/base/gunit.h" | 22 #include "webrtc/base/gunit.h" |
| 23 #include "webrtc/base/helpers.h" | 23 #include "webrtc/base/helpers.h" |
| 24 #include "webrtc/base/messagehandler.h" | 24 #include "webrtc/base/messagehandler.h" |
| 25 #include "webrtc/base/messagequeue.h" | 25 #include "webrtc/base/messagequeue.h" |
| 26 #include "webrtc/base/ssladapter.h" | 26 #include "webrtc/base/ssladapter.h" |
| 27 #include "webrtc/base/thread.h" | 27 #include "webrtc/base/thread.h" |
| 28 #include "webrtc/media/base/mediachannel.h" | 28 #include "webrtc/media/base/mediachannel.h" |
| 29 #include "webrtc/media/base/mediaconstants.h" | 29 #include "webrtc/media/base/mediaconstants.h" |
| 30 #include "webrtc/media/sctp/sctpdataengine.h" | 30 #include "webrtc/media/sctp/sctpdataengine.h" |
| 31 | 31 |
| 32 namespace cricket { |
| 32 enum { | 33 enum { |
| 33 MSG_PACKET = 1, | 34 MSG_PACKET = 1, |
| 34 }; | 35 }; |
| 35 | 36 |
| 36 // Fake NetworkInterface that sends/receives sctp packets. The one in | 37 // Fake NetworkInterface that sends/receives sctp packets. The one in |
| 37 // webrtc/media/base/fakenetworkinterface.h only works with rtp/rtcp. | 38 // webrtc/media/base/fakenetworkinterface.h only works with rtp/rtcp. |
| 38 class SctpFakeNetworkInterface : public cricket::MediaChannel::NetworkInterface, | 39 class SctpFakeNetworkInterface : public MediaChannel::NetworkInterface, |
| 39 public rtc::MessageHandler { | 40 public rtc::MessageHandler { |
| 40 public: | 41 public: |
| 41 explicit SctpFakeNetworkInterface(rtc::Thread* thread) | 42 explicit SctpFakeNetworkInterface(rtc::Thread* thread) |
| 42 : thread_(thread), | 43 : thread_(thread), |
| 43 dest_(NULL) { | 44 dest_(NULL) { |
| 44 } | 45 } |
| 45 | 46 |
| 46 void SetDestination(cricket::DataMediaChannel* dest) { dest_ = dest; } | 47 void SetDestination(DataMediaChannel* dest) { dest_ = dest; } |
| 47 | 48 |
| 48 protected: | 49 protected: |
| 49 // Called to send raw packet down the wire (e.g. SCTP an packet). | 50 // Called to send raw packet down the wire (e.g. SCTP an packet). |
| 50 virtual bool SendPacket(rtc::CopyOnWriteBuffer* packet, | 51 virtual bool SendPacket(rtc::CopyOnWriteBuffer* packet, |
| 51 const rtc::PacketOptions& options) { | 52 const rtc::PacketOptions& options) { |
| 52 LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::SendPacket"; | 53 LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::SendPacket"; |
| 53 | 54 |
| 54 rtc::CopyOnWriteBuffer* buffer = new rtc::CopyOnWriteBuffer(*packet); | 55 rtc::CopyOnWriteBuffer* buffer = new rtc::CopyOnWriteBuffer(*packet); |
| 55 thread_->Post(this, MSG_PACKET, rtc::WrapMessageData(buffer)); | 56 thread_->Post(this, MSG_PACKET, rtc::WrapMessageData(buffer)); |
| 56 LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::SendPacket, Posted message."; | 57 LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::SendPacket, Posted message."; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 84 LOG(LS_WARNING) << "Unsupported: SctpFakeNetworkInterface::SetOption."; | 85 LOG(LS_WARNING) << "Unsupported: SctpFakeNetworkInterface::SetOption."; |
| 85 return 0; | 86 return 0; |
| 86 } | 87 } |
| 87 virtual void SetDefaultDSCPCode(rtc::DiffServCodePoint dscp) { | 88 virtual void SetDefaultDSCPCode(rtc::DiffServCodePoint dscp) { |
| 88 LOG(LS_WARNING) << "Unsupported: SctpFakeNetworkInterface::SetOption."; | 89 LOG(LS_WARNING) << "Unsupported: SctpFakeNetworkInterface::SetOption."; |
| 89 } | 90 } |
| 90 | 91 |
| 91 private: | 92 private: |
| 92 // Not owned by this class. | 93 // Not owned by this class. |
| 93 rtc::Thread* thread_; | 94 rtc::Thread* thread_; |
| 94 cricket::DataMediaChannel* dest_; | 95 DataMediaChannel* dest_; |
| 95 }; | 96 }; |
| 96 | 97 |
| 97 // This is essentially a buffer to hold recieved data. It stores only the last | 98 // This is essentially a buffer to hold recieved data. It stores only the last |
| 98 // received data. Calling OnDataReceived twice overwrites old data with the | 99 // received data. Calling OnDataReceived twice overwrites old data with the |
| 99 // newer one. | 100 // newer one. |
| 100 // TODO(ldixon): Implement constraints, and allow new data to be added to old | 101 // TODO(ldixon): Implement constraints, and allow new data to be added to old |
| 101 // instead of replacing it. | 102 // instead of replacing it. |
| 102 class SctpFakeDataReceiver : public sigslot::has_slots<> { | 103 class SctpFakeDataReceiver : public sigslot::has_slots<> { |
| 103 public: | 104 public: |
| 104 SctpFakeDataReceiver() : received_(false) {} | 105 SctpFakeDataReceiver() : received_(false) {} |
| 105 | 106 |
| 106 void Clear() { | 107 void Clear() { |
| 107 received_ = false; | 108 received_ = false; |
| 108 last_data_ = ""; | 109 last_data_ = ""; |
| 109 last_params_ = cricket::ReceiveDataParams(); | 110 last_params_ = ReceiveDataParams(); |
| 110 } | 111 } |
| 111 | 112 |
| 112 virtual void OnDataReceived(const cricket::ReceiveDataParams& params, | 113 virtual void OnDataReceived(const ReceiveDataParams& params, |
| 113 const char* data, size_t length) { | 114 const char* data, |
| 115 size_t length) { |
| 114 received_ = true; | 116 received_ = true; |
| 115 last_data_ = std::string(data, length); | 117 last_data_ = std::string(data, length); |
| 116 last_params_ = params; | 118 last_params_ = params; |
| 117 } | 119 } |
| 118 | 120 |
| 119 bool received() const { return received_; } | 121 bool received() const { return received_; } |
| 120 std::string last_data() const { return last_data_; } | 122 std::string last_data() const { return last_data_; } |
| 121 cricket::ReceiveDataParams last_params() const { return last_params_; } | 123 ReceiveDataParams last_params() const { return last_params_; } |
| 122 | 124 |
| 123 private: | 125 private: |
| 124 bool received_; | 126 bool received_; |
| 125 std::string last_data_; | 127 std::string last_data_; |
| 126 cricket::ReceiveDataParams last_params_; | 128 ReceiveDataParams last_params_; |
| 127 }; | 129 }; |
| 128 | 130 |
| 129 class SignalReadyToSendObserver : public sigslot::has_slots<> { | 131 class SignalReadyToSendObserver : public sigslot::has_slots<> { |
| 130 public: | 132 public: |
| 131 SignalReadyToSendObserver() : signaled_(false), writable_(false) {} | 133 SignalReadyToSendObserver() : signaled_(false), writable_(false) {} |
| 132 | 134 |
| 133 void OnSignaled(bool writable) { | 135 void OnSignaled(bool writable) { |
| 134 signaled_ = true; | 136 signaled_ = true; |
| 135 writable_ = writable; | 137 writable_ = writable; |
| 136 } | 138 } |
| 137 | 139 |
| 138 bool IsSignaled(bool writable) { | 140 bool IsSignaled(bool writable) { |
| 139 return signaled_ && (writable_ == writable); | 141 return signaled_ && (writable_ == writable); |
| 140 } | 142 } |
| 141 | 143 |
| 142 private: | 144 private: |
| 143 bool signaled_; | 145 bool signaled_; |
| 144 bool writable_; | 146 bool writable_; |
| 145 }; | 147 }; |
| 146 | 148 |
| 147 class SignalChannelClosedObserver : public sigslot::has_slots<> { | 149 class SignalChannelClosedObserver : public sigslot::has_slots<> { |
| 148 public: | 150 public: |
| 149 SignalChannelClosedObserver() {} | 151 SignalChannelClosedObserver() {} |
| 150 void BindSelf(cricket::SctpDataMediaChannel* channel) { | 152 void BindSelf(SctpDataMediaChannel* channel) { |
| 151 channel->SignalStreamClosedRemotely.connect( | 153 channel->SignalStreamClosedRemotely.connect( |
| 152 this, &SignalChannelClosedObserver::OnStreamClosed); | 154 this, &SignalChannelClosedObserver::OnStreamClosed); |
| 153 } | 155 } |
| 154 void OnStreamClosed(uint32_t stream) { streams_.push_back(stream); } | 156 void OnStreamClosed(uint32_t stream) { streams_.push_back(stream); } |
| 155 | 157 |
| 156 int StreamCloseCount(uint32_t stream) { | 158 int StreamCloseCount(uint32_t stream) { |
| 157 return std::count(streams_.begin(), streams_.end(), stream); | 159 return std::count(streams_.begin(), streams_.end(), stream); |
| 158 } | 160 } |
| 159 | 161 |
| 160 bool WasStreamClosed(uint32_t stream) { | 162 bool WasStreamClosed(uint32_t stream) { |
| 161 return std::find(streams_.begin(), streams_.end(), stream) | 163 return std::find(streams_.begin(), streams_.end(), stream) |
| 162 != streams_.end(); | 164 != streams_.end(); |
| 163 } | 165 } |
| 164 | 166 |
| 165 private: | 167 private: |
| 166 std::vector<uint32_t> streams_; | 168 std::vector<uint32_t> streams_; |
| 167 }; | 169 }; |
| 168 | 170 |
| 169 class SignalChannelClosedReopener : public sigslot::has_slots<> { | 171 class SignalChannelClosedReopener : public sigslot::has_slots<> { |
| 170 public: | 172 public: |
| 171 SignalChannelClosedReopener(cricket::SctpDataMediaChannel* channel, | 173 SignalChannelClosedReopener(SctpDataMediaChannel* channel, |
| 172 cricket::SctpDataMediaChannel* peer) | 174 SctpDataMediaChannel* peer) |
| 173 : channel_(channel), peer_(peer) {} | 175 : channel_(channel), peer_(peer) {} |
| 174 | 176 |
| 175 void OnStreamClosed(int stream) { | 177 void OnStreamClosed(int stream) { |
| 176 cricket::StreamParams p(cricket::StreamParams::CreateLegacy(stream)); | 178 StreamParams p(StreamParams::CreateLegacy(stream)); |
| 177 channel_->AddSendStream(p); | 179 channel_->AddSendStream(p); |
| 178 channel_->AddRecvStream(p); | 180 channel_->AddRecvStream(p); |
| 179 peer_->AddSendStream(p); | 181 peer_->AddSendStream(p); |
| 180 peer_->AddRecvStream(p); | 182 peer_->AddRecvStream(p); |
| 181 streams_.push_back(stream); | 183 streams_.push_back(stream); |
| 182 } | 184 } |
| 183 | 185 |
| 184 int StreamCloseCount(int stream) { | 186 int StreamCloseCount(int stream) { |
| 185 return std::count(streams_.begin(), streams_.end(), stream); | 187 return std::count(streams_.begin(), streams_.end(), stream); |
| 186 } | 188 } |
| 187 | 189 |
| 188 private: | 190 private: |
| 189 cricket::SctpDataMediaChannel* channel_; | 191 SctpDataMediaChannel* channel_; |
| 190 cricket::SctpDataMediaChannel* peer_; | 192 SctpDataMediaChannel* peer_; |
| 191 std::vector<int> streams_; | 193 std::vector<int> streams_; |
| 192 }; | 194 }; |
| 193 | 195 |
| 194 // SCTP Data Engine testing framework. | 196 // SCTP Data Engine testing framework. |
| 195 class SctpDataMediaChannelTest : public testing::Test, | 197 class SctpDataMediaChannelTest : public testing::Test, |
| 196 public sigslot::has_slots<> { | 198 public sigslot::has_slots<> { |
| 197 protected: | 199 protected: |
| 198 // usrsctp uses the NSS random number generator on non-Android platforms, | 200 // usrsctp uses the NSS random number generator on non-Android platforms, |
| 199 // so we need to initialize SSL. | 201 // so we need to initialize SSL. |
| 200 static void SetUpTestCase() { | 202 static void SetUpTestCase() { |
| 201 } | 203 } |
| 202 | 204 |
| 203 virtual void SetUp() { | 205 virtual void SetUp() { engine_.reset(new SctpDataEngine()); } |
| 204 engine_.reset(new cricket::SctpDataEngine()); | |
| 205 } | |
| 206 | 206 |
| 207 void SetupConnectedChannels() { | 207 void SetupConnectedChannels() { |
| 208 net1_.reset(new SctpFakeNetworkInterface(rtc::Thread::Current())); | 208 net1_.reset(new SctpFakeNetworkInterface(rtc::Thread::Current())); |
| 209 net2_.reset(new SctpFakeNetworkInterface(rtc::Thread::Current())); | 209 net2_.reset(new SctpFakeNetworkInterface(rtc::Thread::Current())); |
| 210 recv1_.reset(new SctpFakeDataReceiver()); | 210 recv1_.reset(new SctpFakeDataReceiver()); |
| 211 recv2_.reset(new SctpFakeDataReceiver()); | 211 recv2_.reset(new SctpFakeDataReceiver()); |
| 212 chan1_ready_to_send_count_ = 0; | 212 chan1_ready_to_send_count_ = 0; |
| 213 chan2_ready_to_send_count_ = 0; | 213 chan2_ready_to_send_count_ = 0; |
| 214 chan1_.reset(CreateChannel(net1_.get(), recv1_.get())); | 214 chan1_.reset(CreateChannel(net1_.get(), recv1_.get())); |
| 215 chan1_->set_debug_name("chan1/connector"); | 215 chan1_->set_debug_name_for_testing("chan1/connector"); |
| 216 chan1_->SignalReadyToSend.connect( | 216 chan1_->SignalReadyToSend.connect( |
| 217 this, &SctpDataMediaChannelTest::OnChan1ReadyToSend); | 217 this, &SctpDataMediaChannelTest::OnChan1ReadyToSend); |
| 218 chan2_.reset(CreateChannel(net2_.get(), recv2_.get())); | 218 chan2_.reset(CreateChannel(net2_.get(), recv2_.get())); |
| 219 chan2_->set_debug_name("chan2/listener"); | 219 chan2_->set_debug_name_for_testing("chan2/listener"); |
| 220 chan2_->SignalReadyToSend.connect( | 220 chan2_->SignalReadyToSend.connect( |
| 221 this, &SctpDataMediaChannelTest::OnChan2ReadyToSend); | 221 this, &SctpDataMediaChannelTest::OnChan2ReadyToSend); |
| 222 // Setup two connected channels ready to send and receive. | 222 // Setup two connected channels ready to send and receive. |
| 223 net1_->SetDestination(chan2_.get()); | 223 net1_->SetDestination(chan2_.get()); |
| 224 net2_->SetDestination(chan1_.get()); | 224 net2_->SetDestination(chan1_.get()); |
| 225 | 225 |
| 226 LOG(LS_VERBOSE) << "Channel setup ----------------------------- "; | 226 LOG(LS_VERBOSE) << "Channel setup ----------------------------- "; |
| 227 AddStream(1); | 227 AddStream(1); |
| 228 AddStream(2); | 228 AddStream(2); |
| 229 | 229 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 247 channel1()->SetSend(false); | 247 channel1()->SetSend(false); |
| 248 channel2()->SetSend(false); | 248 channel2()->SetSend(false); |
| 249 | 249 |
| 250 // Process messages until idle to prevent a sent packet from being dropped | 250 // Process messages until idle to prevent a sent packet from being dropped |
| 251 // and causing memory leaks (not being deleted by the receiver). | 251 // and causing memory leaks (not being deleted by the receiver). |
| 252 ProcessMessagesUntilIdle(); | 252 ProcessMessagesUntilIdle(); |
| 253 } | 253 } |
| 254 | 254 |
| 255 bool AddStream(int ssrc) { | 255 bool AddStream(int ssrc) { |
| 256 bool ret = true; | 256 bool ret = true; |
| 257 cricket::StreamParams p(cricket::StreamParams::CreateLegacy(ssrc)); | 257 StreamParams p(StreamParams::CreateLegacy(ssrc)); |
| 258 ret = ret && chan1_->AddSendStream(p); | 258 ret = ret && chan1_->AddSendStream(p); |
| 259 ret = ret && chan1_->AddRecvStream(p); | 259 ret = ret && chan1_->AddRecvStream(p); |
| 260 ret = ret && chan2_->AddSendStream(p); | 260 ret = ret && chan2_->AddSendStream(p); |
| 261 ret = ret && chan2_->AddRecvStream(p); | 261 ret = ret && chan2_->AddRecvStream(p); |
| 262 return ret; | 262 return ret; |
| 263 } | 263 } |
| 264 | 264 |
| 265 cricket::SctpDataMediaChannel* CreateChannel( | 265 SctpDataMediaChannel* CreateChannel(SctpFakeNetworkInterface* net, |
| 266 SctpFakeNetworkInterface* net, SctpFakeDataReceiver* recv) { | 266 SctpFakeDataReceiver* recv) { |
| 267 cricket::SctpDataMediaChannel* channel = | 267 SctpDataMediaChannel* channel = |
| 268 static_cast<cricket::SctpDataMediaChannel*>(engine_->CreateChannel( | 268 static_cast<SctpDataMediaChannel*>(engine_->CreateChannel(DCT_SCTP)); |
| 269 cricket::DCT_SCTP)); | |
| 270 channel->SetInterface(net); | 269 channel->SetInterface(net); |
| 271 // When data is received, pass it to the SctpFakeDataReceiver. | 270 // When data is received, pass it to the SctpFakeDataReceiver. |
| 272 channel->SignalDataReceived.connect( | 271 channel->SignalDataReceived.connect( |
| 273 recv, &SctpFakeDataReceiver::OnDataReceived); | 272 recv, &SctpFakeDataReceiver::OnDataReceived); |
| 274 return channel; | 273 return channel; |
| 275 } | 274 } |
| 276 | 275 |
| 277 bool SendData(cricket::SctpDataMediaChannel* chan, | 276 bool SendData(SctpDataMediaChannel* chan, |
| 278 uint32_t ssrc, | 277 uint32_t ssrc, |
| 279 const std::string& msg, | 278 const std::string& msg, |
| 280 cricket::SendDataResult* result) { | 279 SendDataResult* result) { |
| 281 cricket::SendDataParams params; | 280 SendDataParams params; |
| 282 params.ssrc = ssrc; | 281 params.ssrc = ssrc; |
| 283 | 282 |
| 284 return chan->SendData(params, rtc::CopyOnWriteBuffer( | 283 return chan->SendData(params, rtc::CopyOnWriteBuffer( |
| 285 &msg[0], msg.length()), result); | 284 &msg[0], msg.length()), result); |
| 286 } | 285 } |
| 287 | 286 |
| 288 bool ReceivedData(const SctpFakeDataReceiver* recv, | 287 bool ReceivedData(const SctpFakeDataReceiver* recv, |
| 289 uint32_t ssrc, | 288 uint32_t ssrc, |
| 290 const std::string& msg) { | 289 const std::string& msg) { |
| 291 return (recv->received() && | 290 return (recv->received() && |
| 292 recv->last_params().ssrc == ssrc && | 291 recv->last_params().ssrc == ssrc && |
| 293 recv->last_data() == msg); | 292 recv->last_data() == msg); |
| 294 } | 293 } |
| 295 | 294 |
| 296 bool ProcessMessagesUntilIdle() { | 295 bool ProcessMessagesUntilIdle() { |
| 297 rtc::Thread* thread = rtc::Thread::Current(); | 296 rtc::Thread* thread = rtc::Thread::Current(); |
| 298 while (!thread->empty()) { | 297 while (!thread->empty()) { |
| 299 rtc::Message msg; | 298 rtc::Message msg; |
| 300 if (thread->Get(&msg, rtc::Thread::kForever)) { | 299 if (thread->Get(&msg, rtc::Thread::kForever)) { |
| 301 thread->Dispatch(&msg); | 300 thread->Dispatch(&msg); |
| 302 } | 301 } |
| 303 } | 302 } |
| 304 return !thread->IsQuitting(); | 303 return !thread->IsQuitting(); |
| 305 } | 304 } |
| 306 | 305 |
| 307 cricket::SctpDataMediaChannel* channel1() { return chan1_.get(); } | 306 SctpDataMediaChannel* channel1() { return chan1_.get(); } |
| 308 cricket::SctpDataMediaChannel* channel2() { return chan2_.get(); } | 307 SctpDataMediaChannel* channel2() { return chan2_.get(); } |
| 309 SctpFakeDataReceiver* receiver1() { return recv1_.get(); } | 308 SctpFakeDataReceiver* receiver1() { return recv1_.get(); } |
| 310 SctpFakeDataReceiver* receiver2() { return recv2_.get(); } | 309 SctpFakeDataReceiver* receiver2() { return recv2_.get(); } |
| 311 | 310 |
| 312 int channel1_ready_to_send_count() { return chan1_ready_to_send_count_; } | 311 int channel1_ready_to_send_count() { return chan1_ready_to_send_count_; } |
| 313 int channel2_ready_to_send_count() { return chan2_ready_to_send_count_; } | 312 int channel2_ready_to_send_count() { return chan2_ready_to_send_count_; } |
| 314 private: | 313 private: |
| 315 std::unique_ptr<cricket::SctpDataEngine> engine_; | 314 std::unique_ptr<SctpDataEngine> engine_; |
| 316 std::unique_ptr<SctpFakeNetworkInterface> net1_; | 315 std::unique_ptr<SctpFakeNetworkInterface> net1_; |
| 317 std::unique_ptr<SctpFakeNetworkInterface> net2_; | 316 std::unique_ptr<SctpFakeNetworkInterface> net2_; |
| 318 std::unique_ptr<SctpFakeDataReceiver> recv1_; | 317 std::unique_ptr<SctpFakeDataReceiver> recv1_; |
| 319 std::unique_ptr<SctpFakeDataReceiver> recv2_; | 318 std::unique_ptr<SctpFakeDataReceiver> recv2_; |
| 320 std::unique_ptr<cricket::SctpDataMediaChannel> chan1_; | 319 std::unique_ptr<SctpDataMediaChannel> chan1_; |
| 321 std::unique_ptr<cricket::SctpDataMediaChannel> chan2_; | 320 std::unique_ptr<SctpDataMediaChannel> chan2_; |
| 322 | 321 |
| 323 int chan1_ready_to_send_count_; | 322 int chan1_ready_to_send_count_; |
| 324 int chan2_ready_to_send_count_; | 323 int chan2_ready_to_send_count_; |
| 325 | 324 |
| 326 void OnChan1ReadyToSend(bool send) { | 325 void OnChan1ReadyToSend(bool send) { |
| 327 if (send) | 326 if (send) |
| 328 ++chan1_ready_to_send_count_; | 327 ++chan1_ready_to_send_count_; |
| 329 } | 328 } |
| 330 void OnChan2ReadyToSend(bool send) { | 329 void OnChan2ReadyToSend(bool send) { |
| 331 if (send) | 330 if (send) |
| 332 ++chan2_ready_to_send_count_; | 331 ++chan2_ready_to_send_count_; |
| 333 } | 332 } |
| 334 }; | 333 }; |
| 335 | 334 |
| 336 // Verifies that SignalReadyToSend is fired. | 335 // Verifies that SignalReadyToSend is fired. |
| 337 TEST_F(SctpDataMediaChannelTest, SignalReadyToSend) { | 336 TEST_F(SctpDataMediaChannelTest, SignalReadyToSend) { |
| 338 SetupConnectedChannels(); | 337 SetupConnectedChannels(); |
| 339 | 338 |
| 340 SignalReadyToSendObserver signal_observer_1; | 339 SignalReadyToSendObserver signal_observer_1; |
| 341 SignalReadyToSendObserver signal_observer_2; | 340 SignalReadyToSendObserver signal_observer_2; |
| 342 | 341 |
| 343 channel1()->SignalReadyToSend.connect(&signal_observer_1, | 342 channel1()->SignalReadyToSend.connect(&signal_observer_1, |
| 344 &SignalReadyToSendObserver::OnSignaled); | 343 &SignalReadyToSendObserver::OnSignaled); |
| 345 channel2()->SignalReadyToSend.connect(&signal_observer_2, | 344 channel2()->SignalReadyToSend.connect(&signal_observer_2, |
| 346 &SignalReadyToSendObserver::OnSignaled); | 345 &SignalReadyToSendObserver::OnSignaled); |
| 347 | 346 |
| 348 cricket::SendDataResult result; | 347 SendDataResult result; |
| 349 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); | 348 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); |
| 350 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 349 EXPECT_EQ(SDR_SUCCESS, result); |
| 351 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); | 350 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); |
| 352 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); | 351 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); |
| 353 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 352 EXPECT_EQ(SDR_SUCCESS, result); |
| 354 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); | 353 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); |
| 355 | 354 |
| 356 EXPECT_TRUE_WAIT(signal_observer_1.IsSignaled(true), 1000); | 355 EXPECT_TRUE_WAIT(signal_observer_1.IsSignaled(true), 1000); |
| 357 EXPECT_TRUE_WAIT(signal_observer_2.IsSignaled(true), 1000); | 356 EXPECT_TRUE_WAIT(signal_observer_2.IsSignaled(true), 1000); |
| 358 } | 357 } |
| 359 | 358 |
| 360 TEST_F(SctpDataMediaChannelTest, SendData) { | 359 TEST_F(SctpDataMediaChannelTest, SendData) { |
| 361 SetupConnectedChannels(); | 360 SetupConnectedChannels(); |
| 362 | 361 |
| 363 cricket::SendDataResult result; | 362 SendDataResult result; |
| 364 LOG(LS_VERBOSE) << "chan1 sending: 'hello?' -----------------------------"; | 363 LOG(LS_VERBOSE) << "chan1 sending: 'hello?' -----------------------------"; |
| 365 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); | 364 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); |
| 366 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 365 EXPECT_EQ(SDR_SUCCESS, result); |
| 367 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); | 366 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); |
| 368 LOG(LS_VERBOSE) << "recv2.received=" << receiver2()->received() | 367 LOG(LS_VERBOSE) << "recv2.received=" << receiver2()->received() |
| 369 << ", recv2.last_params.ssrc=" | 368 << ", recv2.last_params.ssrc=" |
| 370 << receiver2()->last_params().ssrc | 369 << receiver2()->last_params().ssrc |
| 371 << ", recv2.last_params.timestamp=" | 370 << ", recv2.last_params.timestamp=" |
| 372 << receiver2()->last_params().ssrc | 371 << receiver2()->last_params().ssrc |
| 373 << ", recv2.last_params.seq_num=" | 372 << ", recv2.last_params.seq_num=" |
| 374 << receiver2()->last_params().seq_num | 373 << receiver2()->last_params().seq_num |
| 375 << ", recv2.last_data=" << receiver2()->last_data(); | 374 << ", recv2.last_data=" << receiver2()->last_data(); |
| 376 | 375 |
| 377 LOG(LS_VERBOSE) << "chan2 sending: 'hi chan1' -----------------------------"; | 376 LOG(LS_VERBOSE) << "chan2 sending: 'hi chan1' -----------------------------"; |
| 378 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); | 377 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); |
| 379 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 378 EXPECT_EQ(SDR_SUCCESS, result); |
| 380 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); | 379 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); |
| 381 LOG(LS_VERBOSE) << "recv1.received=" << receiver1()->received() | 380 LOG(LS_VERBOSE) << "recv1.received=" << receiver1()->received() |
| 382 << ", recv1.last_params.ssrc=" | 381 << ", recv1.last_params.ssrc=" |
| 383 << receiver1()->last_params().ssrc | 382 << receiver1()->last_params().ssrc |
| 384 << ", recv1.last_params.timestamp=" | 383 << ", recv1.last_params.timestamp=" |
| 385 << receiver1()->last_params().ssrc | 384 << receiver1()->last_params().ssrc |
| 386 << ", recv1.last_params.seq_num=" | 385 << ", recv1.last_params.seq_num=" |
| 387 << receiver1()->last_params().seq_num | 386 << receiver1()->last_params().seq_num |
| 388 << ", recv1.last_data=" << receiver1()->last_data(); | 387 << ", recv1.last_data=" << receiver1()->last_data(); |
| 389 } | 388 } |
| 390 | 389 |
| 391 // Sends a lot of large messages at once and verifies SDR_BLOCK is returned. | 390 // Sends a lot of large messages at once and verifies SDR_BLOCK is returned. |
| 392 TEST_F(SctpDataMediaChannelTest, SendDataBlocked) { | 391 TEST_F(SctpDataMediaChannelTest, SendDataBlocked) { |
| 393 SetupConnectedChannels(); | 392 SetupConnectedChannels(); |
| 394 | 393 |
| 395 cricket::SendDataResult result; | 394 SendDataResult result; |
| 396 cricket::SendDataParams params; | 395 SendDataParams params; |
| 397 params.ssrc = 1; | 396 params.ssrc = 1; |
| 398 | 397 |
| 399 std::vector<char> buffer(1024 * 64, 0); | 398 std::vector<char> buffer(1024 * 64, 0); |
| 400 | 399 |
| 401 for (size_t i = 0; i < 100; ++i) { | 400 for (size_t i = 0; i < 100; ++i) { |
| 402 channel1()->SendData( | 401 channel1()->SendData( |
| 403 params, rtc::CopyOnWriteBuffer(&buffer[0], buffer.size()), &result); | 402 params, rtc::CopyOnWriteBuffer(&buffer[0], buffer.size()), &result); |
| 404 if (result == cricket::SDR_BLOCK) | 403 if (result == SDR_BLOCK) |
| 405 break; | 404 break; |
| 406 } | 405 } |
| 407 | 406 |
| 408 EXPECT_EQ(cricket::SDR_BLOCK, result); | 407 EXPECT_EQ(SDR_BLOCK, result); |
| 409 } | 408 } |
| 410 | 409 |
| 411 TEST_F(SctpDataMediaChannelTest, ClosesRemoteStream) { | 410 TEST_F(SctpDataMediaChannelTest, ClosesRemoteStream) { |
| 412 SetupConnectedChannels(); | 411 SetupConnectedChannels(); |
| 413 SignalChannelClosedObserver chan_1_sig_receiver, chan_2_sig_receiver; | 412 SignalChannelClosedObserver chan_1_sig_receiver, chan_2_sig_receiver; |
| 414 chan_1_sig_receiver.BindSelf(channel1()); | 413 chan_1_sig_receiver.BindSelf(channel1()); |
| 415 chan_2_sig_receiver.BindSelf(channel2()); | 414 chan_2_sig_receiver.BindSelf(channel2()); |
| 416 | 415 |
| 417 cricket::SendDataResult result; | 416 SendDataResult result; |
| 418 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); | 417 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); |
| 419 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 418 EXPECT_EQ(SDR_SUCCESS, result); |
| 420 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); | 419 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); |
| 421 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); | 420 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); |
| 422 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 421 EXPECT_EQ(SDR_SUCCESS, result); |
| 423 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); | 422 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); |
| 424 | 423 |
| 425 // Close channel 1. Channel 2 should notify us. | 424 // Close channel 1. Channel 2 should notify us. |
| 426 channel1()->RemoveSendStream(1); | 425 channel1()->RemoveSendStream(1); |
| 427 EXPECT_TRUE_WAIT(chan_2_sig_receiver.WasStreamClosed(1), 1000); | 426 EXPECT_TRUE_WAIT(chan_2_sig_receiver.WasStreamClosed(1), 1000); |
| 428 } | 427 } |
| 429 | 428 |
| 430 TEST_F(SctpDataMediaChannelTest, ClosesTwoRemoteStreams) { | 429 TEST_F(SctpDataMediaChannelTest, ClosesTwoRemoteStreams) { |
| 431 SetupConnectedChannels(); | 430 SetupConnectedChannels(); |
| 432 AddStream(3); | 431 AddStream(3); |
| 433 SignalChannelClosedObserver chan_1_sig_receiver, chan_2_sig_receiver; | 432 SignalChannelClosedObserver chan_1_sig_receiver, chan_2_sig_receiver; |
| 434 chan_1_sig_receiver.BindSelf(channel1()); | 433 chan_1_sig_receiver.BindSelf(channel1()); |
| 435 chan_2_sig_receiver.BindSelf(channel2()); | 434 chan_2_sig_receiver.BindSelf(channel2()); |
| 436 | 435 |
| 437 cricket::SendDataResult result; | 436 SendDataResult result; |
| 438 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); | 437 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); |
| 439 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 438 EXPECT_EQ(SDR_SUCCESS, result); |
| 440 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); | 439 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); |
| 441 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); | 440 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); |
| 442 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 441 EXPECT_EQ(SDR_SUCCESS, result); |
| 443 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); | 442 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); |
| 444 | 443 |
| 445 // Close two streams on one side. | 444 // Close two streams on one side. |
| 446 channel2()->RemoveSendStream(2); | 445 channel2()->RemoveSendStream(2); |
| 447 channel2()->RemoveSendStream(3); | 446 channel2()->RemoveSendStream(3); |
| 448 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(2), 1000); | 447 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(2), 1000); |
| 449 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(3), 1000); | 448 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(3), 1000); |
| 450 } | 449 } |
| 451 | 450 |
| 452 TEST_F(SctpDataMediaChannelTest, ClosesStreamsOnBothSides) { | 451 TEST_F(SctpDataMediaChannelTest, ClosesStreamsOnBothSides) { |
| 453 SetupConnectedChannels(); | 452 SetupConnectedChannels(); |
| 454 AddStream(3); | 453 AddStream(3); |
| 455 AddStream(4); | 454 AddStream(4); |
| 456 SignalChannelClosedObserver chan_1_sig_receiver, chan_2_sig_receiver; | 455 SignalChannelClosedObserver chan_1_sig_receiver, chan_2_sig_receiver; |
| 457 chan_1_sig_receiver.BindSelf(channel1()); | 456 chan_1_sig_receiver.BindSelf(channel1()); |
| 458 chan_2_sig_receiver.BindSelf(channel2()); | 457 chan_2_sig_receiver.BindSelf(channel2()); |
| 459 | 458 |
| 460 cricket::SendDataResult result; | 459 SendDataResult result; |
| 461 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); | 460 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); |
| 462 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 461 EXPECT_EQ(SDR_SUCCESS, result); |
| 463 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); | 462 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); |
| 464 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); | 463 ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); |
| 465 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 464 EXPECT_EQ(SDR_SUCCESS, result); |
| 466 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); | 465 EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); |
| 467 | 466 |
| 468 // Close one stream on channel1(), while closing three streams on | 467 // Close one stream on channel1(), while closing three streams on |
| 469 // channel2(). They will conflict (only one side can close anything at a | 468 // channel2(). They will conflict (only one side can close anything at a |
| 470 // time, apparently). Test the resolution of the conflict. | 469 // time, apparently). Test the resolution of the conflict. |
| 471 channel1()->RemoveSendStream(1); | 470 channel1()->RemoveSendStream(1); |
| 472 | 471 |
| 473 channel2()->RemoveSendStream(2); | 472 channel2()->RemoveSendStream(2); |
| 474 channel2()->RemoveSendStream(3); | 473 channel2()->RemoveSendStream(3); |
| 475 channel2()->RemoveSendStream(4); | 474 channel2()->RemoveSendStream(4); |
| 476 EXPECT_TRUE_WAIT(chan_2_sig_receiver.WasStreamClosed(1), 1000); | 475 EXPECT_TRUE_WAIT(chan_2_sig_receiver.WasStreamClosed(1), 1000); |
| 477 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(2), 1000); | 476 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(2), 1000); |
| 478 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(3), 1000); | 477 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(3), 1000); |
| 479 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(4), 1000); | 478 EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(4), 1000); |
| 480 } | 479 } |
| 481 | 480 |
| 482 TEST_F(SctpDataMediaChannelTest, EngineSignalsRightChannel) { | 481 TEST_F(SctpDataMediaChannelTest, EngineSignalsRightChannel) { |
| 483 SetupConnectedChannels(); | 482 SetupConnectedChannels(); |
| 484 EXPECT_TRUE_WAIT(channel1()->socket() != NULL, 1000); | 483 EXPECT_TRUE_WAIT(channel1()->socket() != NULL, 1000); |
| 485 struct socket *sock = const_cast<struct socket*>(channel1()->socket()); | 484 struct socket *sock = const_cast<struct socket*>(channel1()->socket()); |
| 486 int prior_count = channel1_ready_to_send_count(); | 485 int prior_count = channel1_ready_to_send_count(); |
| 487 cricket::SctpDataEngine::SendThresholdCallback(sock, 0); | 486 SctpDataMediaChannel::SendThresholdCallback(sock, 0); |
| 488 EXPECT_GT(channel1_ready_to_send_count(), prior_count); | 487 EXPECT_GT(channel1_ready_to_send_count(), prior_count); |
| 489 } | 488 } |
| 490 | 489 |
| 491 TEST_F(SctpDataMediaChannelTest, RefusesHighNumberedChannels) { | 490 TEST_F(SctpDataMediaChannelTest, RefusesHighNumberedChannels) { |
| 492 SetupConnectedChannels(); | 491 SetupConnectedChannels(); |
| 493 EXPECT_TRUE(AddStream(1022)); | 492 EXPECT_TRUE(AddStream(1022)); |
| 494 EXPECT_FALSE(AddStream(1023)); | 493 EXPECT_FALSE(AddStream(1023)); |
| 495 } | 494 } |
| 496 | 495 |
| 497 // Flaky on Linux and Windows. See webrtc:4453. | 496 // Flaky on Linux and Windows. See webrtc:4453. |
| 498 #if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX) | 497 #if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX) |
| 499 #define MAYBE_ReusesAStream DISABLED_ReusesAStream | 498 #define MAYBE_ReusesAStream DISABLED_ReusesAStream |
| 500 #else | 499 #else |
| 501 #define MAYBE_ReusesAStream ReusesAStream | 500 #define MAYBE_ReusesAStream ReusesAStream |
| 502 #endif | 501 #endif |
| 503 TEST_F(SctpDataMediaChannelTest, MAYBE_ReusesAStream) { | 502 TEST_F(SctpDataMediaChannelTest, MAYBE_ReusesAStream) { |
| 504 // Shut down channel 1, then open it up again for reuse. | 503 // Shut down channel 1, then open it up again for reuse. |
| 505 SetupConnectedChannels(); | 504 SetupConnectedChannels(); |
| 506 cricket::SendDataResult result; | 505 SendDataResult result; |
| 507 SignalChannelClosedObserver chan_2_sig_receiver; | 506 SignalChannelClosedObserver chan_2_sig_receiver; |
| 508 chan_2_sig_receiver.BindSelf(channel2()); | 507 chan_2_sig_receiver.BindSelf(channel2()); |
| 509 | 508 |
| 510 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); | 509 ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); |
| 511 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 510 EXPECT_EQ(SDR_SUCCESS, result); |
| 512 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); | 511 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); |
| 513 | 512 |
| 514 channel1()->RemoveSendStream(1); | 513 channel1()->RemoveSendStream(1); |
| 515 EXPECT_TRUE_WAIT(chan_2_sig_receiver.WasStreamClosed(1), 1000); | 514 EXPECT_TRUE_WAIT(chan_2_sig_receiver.WasStreamClosed(1), 1000); |
| 516 // Channel 1 is gone now. | 515 // Channel 1 is gone now. |
| 517 | 516 |
| 518 // Create a new channel 1. | 517 // Create a new channel 1. |
| 519 AddStream(1); | 518 AddStream(1); |
| 520 ASSERT_TRUE(SendData(channel1(), 1, "hi?", &result)); | 519 ASSERT_TRUE(SendData(channel1(), 1, "hi?", &result)); |
| 521 EXPECT_EQ(cricket::SDR_SUCCESS, result); | 520 EXPECT_EQ(SDR_SUCCESS, result); |
| 522 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hi?"), 1000); | 521 EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hi?"), 1000); |
| 523 channel1()->RemoveSendStream(1); | 522 channel1()->RemoveSendStream(1); |
| 524 EXPECT_TRUE_WAIT(chan_2_sig_receiver.StreamCloseCount(1) == 2, 1000); | 523 EXPECT_TRUE_WAIT(chan_2_sig_receiver.StreamCloseCount(1) == 2, 1000); |
| 525 } | 524 } |
| 525 |
| 526 } // namespace cricket |
| OLD | NEW |