128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/* 25f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * libjingle 35f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * Copyright 2013 Google Inc. 428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * this list of conditions and the following disclaimer. 1028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 1128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 1228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * and/or other materials provided with the distribution. 1328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 1428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * derived from this software without specific prior written permission. 1528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 1628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 1728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 1928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 2728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <errno.h> 2928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <stdarg.h> 3028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <stdio.h> 3128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <string> 32f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org#include <vector> 3328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 34a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "talk/media/base/constants.h" 35a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "talk/media/base/mediachannel.h" 36a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "talk/media/sctp/sctpdataengine.h" 37d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/bind.h" 38d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/buffer.h" 39d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/criticalsection.h" 40d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/gunit.h" 41d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/helpers.h" 42d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/messagehandler.h" 43d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/messagequeue.h" 44d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/scoped_ptr.h" 45d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/ssladapter.h" 46d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/thread.h" 4728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgenum { 4928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MSG_PACKET = 1, 5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 5128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Fake NetworkInterface that sends/receives sctp packets. The one in 5328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// talk/media/base/fakenetworkinterface.h only works with rtp/rtcp. 5428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgclass SctpFakeNetworkInterface : public cricket::MediaChannel::NetworkInterface, 55d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org public rtc::MessageHandler { 5628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org public: 57d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org explicit SctpFakeNetworkInterface(rtc::Thread* thread) 5828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : thread_(thread), 5928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org dest_(NULL) { 6028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 6128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org void SetDestination(cricket::DataMediaChannel* dest) { dest_ = dest; } 6328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org protected: 6528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Called to send raw packet down the wire (e.g. SCTP an packet). 66d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org virtual bool SendPacket(rtc::Buffer* packet, 67c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan const rtc::PacketOptions& options) { 6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::SendPacket"; 6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(ldixon): Can/should we use Buffer.TransferTo here? 7128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Note: this assignment does a deep copy of data from packet. 72eebcab5ce99d3e8641dd92a569916b0d24e29fcakwiberg@webrtc.org rtc::Buffer* buffer = new rtc::Buffer(packet->data(), packet->size()); 73d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org thread_->Post(this, MSG_PACKET, rtc::WrapMessageData(buffer)); 7428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::SendPacket, Posted message."; 7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Called when a raw packet has been recieved. This passes the data to the 7928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // code that will interpret the packet. e.g. to get the content payload from 8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // an SCTP packet. 81d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org virtual void OnMessage(rtc::Message* msg) { 8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_VERBOSE) << "SctpFakeNetworkInterface::OnMessage"; 83d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::scoped_ptr<rtc::Buffer> buffer( 84d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org static_cast<rtc::TypedMessageData<rtc::Buffer*>*>( 85acede34aea92cb07049e187341a132f92a34662ajiayl@webrtc.org msg->pdata)->data()); 8628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (dest_) { 87d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org dest_->OnPacketReceived(buffer.get(), rtc::PacketTime()); 8828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 89acede34aea92cb07049e187341a132f92a34662ajiayl@webrtc.org delete msg->pdata; 9028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 9128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Unsupported functions required to exist by NetworkInterface. 9328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(ldixon): Refactor parent NetworkInterface class so these are not 9428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // required. They are RTC specific and should be in an appropriate subclass. 95d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org virtual bool SendRtcp(rtc::Buffer* packet, 96c1aeaf0dc37d96f31c92f893f4e30e7a5f7cc2b7stefan const rtc::PacketOptions& options) { 9728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Unsupported: SctpFakeNetworkInterface::SendRtcp."; 9828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 9928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 100d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org virtual int SetOption(SocketType type, rtc::Socket::Option opt, 10128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int option) { 10228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Unsupported: SctpFakeNetworkInterface::SetOption."; 10328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return 0; 10428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 105d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org virtual void SetDefaultDSCPCode(rtc::DiffServCodePoint dscp) { 1061112c30e1e5f5c7b4b517c4954ef3f15b989a996mallinath@webrtc.org LOG(LS_WARNING) << "Unsupported: SctpFakeNetworkInterface::SetOption."; 1071112c30e1e5f5c7b4b517c4954ef3f15b989a996mallinath@webrtc.org } 10828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 10928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org private: 11028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Not owned by this class. 111d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Thread* thread_; 11228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::DataMediaChannel* dest_; 11328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 11428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 11528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// This is essentially a buffer to hold recieved data. It stores only the last 11628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// received data. Calling OnDataReceived twice overwrites old data with the 11728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// newer one. 11828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// TODO(ldixon): Implement constraints, and allow new data to be added to old 11928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// instead of replacing it. 12028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgclass SctpFakeDataReceiver : public sigslot::has_slots<> { 12128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org public: 12228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SctpFakeDataReceiver() : received_(false) {} 12328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 12428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org void Clear() { 12528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org received_ = false; 12628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org last_data_ = ""; 12728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org last_params_ = cricket::ReceiveDataParams(); 12828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 12928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 13028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org virtual void OnDataReceived(const cricket::ReceiveDataParams& params, 13128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const char* data, size_t length) { 13228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org received_ = true; 13328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org last_data_ = std::string(data, length); 13428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org last_params_ = params; 13528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 13628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 13728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool received() const { return received_; } 13828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::string last_data() const { return last_data_; } 13928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::ReceiveDataParams last_params() const { return last_params_; } 14028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 14128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org private: 14228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool received_; 14328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::string last_data_; 14428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::ReceiveDataParams last_params_; 14528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 14628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 147d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.orgclass SignalReadyToSendObserver : public sigslot::has_slots<> { 148d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org public: 149d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org SignalReadyToSendObserver() : signaled_(false), writable_(false) {} 150d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 151d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org void OnSignaled(bool writable) { 152d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org signaled_ = true; 153d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org writable_ = writable; 154d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org } 155d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 156d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org bool IsSignaled(bool writable) { 157d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org return signaled_ && (writable_ == writable); 158d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org } 159d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 160d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org private: 161d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org bool signaled_; 162d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org bool writable_; 163d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org}; 164d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 165f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.orgclass SignalChannelClosedObserver : public sigslot::has_slots<> { 166f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org public: 167f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SignalChannelClosedObserver() {} 168f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org void BindSelf(cricket::SctpDataMediaChannel* channel) { 1691d66be22c8f929e1170f288472aac9d4b44b7a05buildbot@webrtc.org channel->SignalStreamClosedRemotely.connect( 170f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org this, &SignalChannelClosedObserver::OnStreamClosed); 171f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org } 1720c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström void OnStreamClosed(uint32_t stream) { streams_.push_back(stream); } 173f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 1740c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int StreamCloseCount(uint32_t stream) { 175f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org return std::count(streams_.begin(), streams_.end(), stream); 176f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org } 177f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 1780c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström bool WasStreamClosed(uint32_t stream) { 179f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org return std::find(streams_.begin(), streams_.end(), stream) 180f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org != streams_.end(); 181f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org } 182f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 183f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org private: 1840c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström std::vector<uint32_t> streams_; 185f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org}; 186f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 187f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.orgclass SignalChannelClosedReopener : public sigslot::has_slots<> { 188f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org public: 189f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SignalChannelClosedReopener(cricket::SctpDataMediaChannel* channel, 190f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org cricket::SctpDataMediaChannel* peer) 191f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org : channel_(channel), peer_(peer) {} 192f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 193f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org void OnStreamClosed(int stream) { 194f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org cricket::StreamParams p(cricket::StreamParams::CreateLegacy(stream)); 195f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel_->AddSendStream(p); 196f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel_->AddRecvStream(p); 197f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org peer_->AddSendStream(p); 198f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org peer_->AddRecvStream(p); 199f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org streams_.push_back(stream); 200f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org } 201f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 202f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org int StreamCloseCount(int stream) { 203f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org return std::count(streams_.begin(), streams_.end(), stream); 204f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org } 205f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 206f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org private: 207f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org cricket::SctpDataMediaChannel* channel_; 208f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org cricket::SctpDataMediaChannel* peer_; 209f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org std::vector<int> streams_; 210f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org}; 211f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 21228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// SCTP Data Engine testing framework. 2131d1ffc9ad267d7e6e9ec9001052fd4abf29d7622wu@webrtc.orgclass SctpDataMediaChannelTest : public testing::Test, 2141d1ffc9ad267d7e6e9ec9001052fd4abf29d7622wu@webrtc.org public sigslot::has_slots<> { 21528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org protected: 216a576faf82a692c9422dcdc3278394ed25e6ee4f7jiayl@webrtc.org // usrsctp uses the NSS random number generator on non-Android platforms, 217a576faf82a692c9422dcdc3278394ed25e6ee4f7jiayl@webrtc.org // so we need to initialize SSL. 218a576faf82a692c9422dcdc3278394ed25e6ee4f7jiayl@webrtc.org static void SetUpTestCase() { 219a576faf82a692c9422dcdc3278394ed25e6ee4f7jiayl@webrtc.org } 220a576faf82a692c9422dcdc3278394ed25e6ee4f7jiayl@webrtc.org 22128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org virtual void SetUp() { 22228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org engine_.reset(new cricket::SctpDataEngine()); 22328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 22428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 225d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org void SetupConnectedChannels() { 226d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org net1_.reset(new SctpFakeNetworkInterface(rtc::Thread::Current())); 227d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org net2_.reset(new SctpFakeNetworkInterface(rtc::Thread::Current())); 228d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org recv1_.reset(new SctpFakeDataReceiver()); 229d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org recv2_.reset(new SctpFakeDataReceiver()); 230e8386d21992b6683b6fadd315ea631875b4256fbLally Singh chan1_ready_to_send_count_ = 0; 231e8386d21992b6683b6fadd315ea631875b4256fbLally Singh chan2_ready_to_send_count_ = 0; 232d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org chan1_.reset(CreateChannel(net1_.get(), recv1_.get())); 233d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org chan1_->set_debug_name("chan1/connector"); 234e8386d21992b6683b6fadd315ea631875b4256fbLally Singh chan1_->SignalReadyToSend.connect( 235e8386d21992b6683b6fadd315ea631875b4256fbLally Singh this, &SctpDataMediaChannelTest::OnChan1ReadyToSend); 236d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org chan2_.reset(CreateChannel(net2_.get(), recv2_.get())); 237d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org chan2_->set_debug_name("chan2/listener"); 238e8386d21992b6683b6fadd315ea631875b4256fbLally Singh chan2_->SignalReadyToSend.connect( 239e8386d21992b6683b6fadd315ea631875b4256fbLally Singh this, &SctpDataMediaChannelTest::OnChan2ReadyToSend); 240d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org // Setup two connected channels ready to send and receive. 241d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org net1_->SetDestination(chan2_.get()); 242d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org net2_->SetDestination(chan1_.get()); 243d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 244d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org LOG(LS_VERBOSE) << "Channel setup ----------------------------- "; 245f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org AddStream(1); 246f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org AddStream(2); 247d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 248d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org LOG(LS_VERBOSE) << "Connect the channels -----------------------------"; 249d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org // chan1 wants to setup a data connection. 250d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org chan1_->SetReceive(true); 251d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org // chan1 will have sent chan2 a request to setup a data connection. After 252d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org // chan2 accepts the offer, chan2 connects to chan1 with the following. 253d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org chan2_->SetReceive(true); 254d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org chan2_->SetSend(true); 255d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org // Makes sure that network packets are delivered and simulates a 256d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org // deterministic and realistic small timing delay between the SetSend calls. 257d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org ProcessMessagesUntilIdle(); 258d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 259d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org // chan1 and chan2 are now connected so chan1 enables sending to complete 260d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org // the creation of the connection. 261d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org chan1_->SetSend(true); 262d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org } 263d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 264f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org virtual void TearDown() { 265f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel1()->SetSend(false); 266f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel2()->SetSend(false); 2677118e6166924b569805552253aebd8ae6e370bf3pbos@webrtc.org 2687118e6166924b569805552253aebd8ae6e370bf3pbos@webrtc.org // Process messages until idle to prevent a sent packet from being dropped 2697118e6166924b569805552253aebd8ae6e370bf3pbos@webrtc.org // and causing memory leaks (not being deleted by the receiver). 2707118e6166924b569805552253aebd8ae6e370bf3pbos@webrtc.org ProcessMessagesUntilIdle(); 271f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org } 272f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 27327ed3cc28cf950456a0c66d7a10656a96832feddlally bool AddStream(int ssrc) { 27427ed3cc28cf950456a0c66d7a10656a96832feddlally bool ret = true; 275f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org cricket::StreamParams p(cricket::StreamParams::CreateLegacy(ssrc)); 27627ed3cc28cf950456a0c66d7a10656a96832feddlally ret = ret && chan1_->AddSendStream(p); 27727ed3cc28cf950456a0c66d7a10656a96832feddlally ret = ret && chan1_->AddRecvStream(p); 27827ed3cc28cf950456a0c66d7a10656a96832feddlally ret = ret && chan2_->AddSendStream(p); 27927ed3cc28cf950456a0c66d7a10656a96832feddlally ret = ret && chan2_->AddRecvStream(p); 28027ed3cc28cf950456a0c66d7a10656a96832feddlally return ret; 281f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org } 282f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 28328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::SctpDataMediaChannel* CreateChannel( 284f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SctpFakeNetworkInterface* net, SctpFakeDataReceiver* recv) { 28528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::SctpDataMediaChannel* channel = 28628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org static_cast<cricket::SctpDataMediaChannel*>(engine_->CreateChannel( 28728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::DCT_SCTP)); 28828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org channel->SetInterface(net); 28928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // When data is received, pass it to the SctpFakeDataReceiver. 29028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org channel->SignalDataReceived.connect( 29128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org recv, &SctpFakeDataReceiver::OnDataReceived); 29228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return channel; 29328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 29428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2950c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström bool SendData(cricket::SctpDataMediaChannel* chan, 2960c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc, 29728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const std::string& msg, 29828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::SendDataResult* result) { 29928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::SendDataParams params; 30028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org params.ssrc = ssrc; 301aebb1ade9d760841f243e380fa22b7ecff2d3ecchenrika@webrtc.org 302d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org return chan->SendData(params, rtc::Buffer( 303f8063d34deefb55b4a0e5091fc59d5d5e58e43d8jiayl@webrtc.org &msg[0], msg.length()), result); 30428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 30528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3060c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström bool ReceivedData(const SctpFakeDataReceiver* recv, 3070c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström uint32_t ssrc, 3080c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström const std::string& msg) { 30928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return (recv->received() && 31028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org recv->last_params().ssrc == ssrc && 31128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org recv->last_data() == msg); 31228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 31328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 31428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool ProcessMessagesUntilIdle() { 315d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Thread* thread = rtc::Thread::Current(); 31628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org while (!thread->empty()) { 317d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Message msg; 31853d9012faf32eb711681fdeb31b9d0d2f9e9481bandresp@webrtc.org if (thread->Get(&msg, rtc::Thread::kForever)) { 31928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org thread->Dispatch(&msg); 32028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 32128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 32228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return !thread->IsQuitting(); 32328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 32428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 325d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org cricket::SctpDataMediaChannel* channel1() { return chan1_.get(); } 326d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org cricket::SctpDataMediaChannel* channel2() { return chan2_.get(); } 327d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org SctpFakeDataReceiver* receiver1() { return recv1_.get(); } 328d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org SctpFakeDataReceiver* receiver2() { return recv2_.get(); } 329d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 330e8386d21992b6683b6fadd315ea631875b4256fbLally Singh int channel1_ready_to_send_count() { return chan1_ready_to_send_count_; } 331e8386d21992b6683b6fadd315ea631875b4256fbLally Singh int channel2_ready_to_send_count() { return chan2_ready_to_send_count_; } 33228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org private: 333d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::scoped_ptr<cricket::SctpDataEngine> engine_; 334d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::scoped_ptr<SctpFakeNetworkInterface> net1_; 335d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::scoped_ptr<SctpFakeNetworkInterface> net2_; 336d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::scoped_ptr<SctpFakeDataReceiver> recv1_; 337d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::scoped_ptr<SctpFakeDataReceiver> recv2_; 338d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::scoped_ptr<cricket::SctpDataMediaChannel> chan1_; 339d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::scoped_ptr<cricket::SctpDataMediaChannel> chan2_; 340e8386d21992b6683b6fadd315ea631875b4256fbLally Singh 341e8386d21992b6683b6fadd315ea631875b4256fbLally Singh int chan1_ready_to_send_count_; 342e8386d21992b6683b6fadd315ea631875b4256fbLally Singh int chan2_ready_to_send_count_; 343e8386d21992b6683b6fadd315ea631875b4256fbLally Singh 344e8386d21992b6683b6fadd315ea631875b4256fbLally Singh void OnChan1ReadyToSend(bool send) { 345e8386d21992b6683b6fadd315ea631875b4256fbLally Singh if (send) 346e8386d21992b6683b6fadd315ea631875b4256fbLally Singh ++chan1_ready_to_send_count_; 347e8386d21992b6683b6fadd315ea631875b4256fbLally Singh } 348e8386d21992b6683b6fadd315ea631875b4256fbLally Singh void OnChan2ReadyToSend(bool send) { 349e8386d21992b6683b6fadd315ea631875b4256fbLally Singh if (send) 350e8386d21992b6683b6fadd315ea631875b4256fbLally Singh ++chan2_ready_to_send_count_; 351e8386d21992b6683b6fadd315ea631875b4256fbLally Singh } 35228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 35328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 354d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org// Verifies that SignalReadyToSend is fired. 355d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.orgTEST_F(SctpDataMediaChannelTest, SignalReadyToSend) { 356d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org SetupConnectedChannels(); 357d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 358d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org SignalReadyToSendObserver signal_observer_1; 359d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org SignalReadyToSendObserver signal_observer_2; 360d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 361d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org channel1()->SignalReadyToSend.connect(&signal_observer_1, 362d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org &SignalReadyToSendObserver::OnSignaled); 363d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org channel2()->SignalReadyToSend.connect(&signal_observer_2, 364d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org &SignalReadyToSendObserver::OnSignaled); 365d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 366d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org cricket::SendDataResult result; 367d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); 368d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 369d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); 370d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); 371d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 372d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); 373d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 374d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org EXPECT_TRUE_WAIT(signal_observer_1.IsSignaled(true), 1000); 375d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org EXPECT_TRUE_WAIT(signal_observer_2.IsSignaled(true), 1000); 376d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org} 377d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org 37828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgTEST_F(SctpDataMediaChannelTest, SendData) { 379d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org SetupConnectedChannels(); 38028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 38128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::SendDataResult result; 38228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_VERBOSE) << "chan1 sending: 'hello?' -----------------------------"; 383d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); 38428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 385d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); 386d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org LOG(LS_VERBOSE) << "recv2.received=" << receiver2()->received() 387f8063d34deefb55b4a0e5091fc59d5d5e58e43d8jiayl@webrtc.org << ", recv2.last_params.ssrc=" 388d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org << receiver2()->last_params().ssrc 389f8063d34deefb55b4a0e5091fc59d5d5e58e43d8jiayl@webrtc.org << ", recv2.last_params.timestamp=" 390d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org << receiver2()->last_params().ssrc 391f8063d34deefb55b4a0e5091fc59d5d5e58e43d8jiayl@webrtc.org << ", recv2.last_params.seq_num=" 392d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org << receiver2()->last_params().seq_num 393f8063d34deefb55b4a0e5091fc59d5d5e58e43d8jiayl@webrtc.org << ", recv2.last_data=" << receiver2()->last_data(); 39428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 39528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_VERBOSE) << "chan2 sending: 'hi chan1' -----------------------------"; 396d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); 39728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 398d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); 399d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org LOG(LS_VERBOSE) << "recv1.received=" << receiver1()->received() 400f8063d34deefb55b4a0e5091fc59d5d5e58e43d8jiayl@webrtc.org << ", recv1.last_params.ssrc=" 401d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org << receiver1()->last_params().ssrc 402f8063d34deefb55b4a0e5091fc59d5d5e58e43d8jiayl@webrtc.org << ", recv1.last_params.timestamp=" 403d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org << receiver1()->last_params().ssrc 404f8063d34deefb55b4a0e5091fc59d5d5e58e43d8jiayl@webrtc.org << ", recv1.last_params.seq_num=" 405d64719d8954262fee94e7615422f3d027dc1ae6bwu@webrtc.org << receiver1()->last_params().seq_num 406f8063d34deefb55b4a0e5091fc59d5d5e58e43d8jiayl@webrtc.org << ", recv1.last_data=" << receiver1()->last_data(); 40728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 4081d1ffc9ad267d7e6e9ec9001052fd4abf29d7622wu@webrtc.org 409f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org// Sends a lot of large messages at once and verifies SDR_BLOCK is returned. 410f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.orgTEST_F(SctpDataMediaChannelTest, SendDataBlocked) { 411f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org SetupConnectedChannels(); 412f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org 413f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org cricket::SendDataResult result; 414f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org cricket::SendDataParams params; 415f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org params.ssrc = 1; 416f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org 417f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org std::vector<char> buffer(1024 * 64, 0); 418f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org 419f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org for (size_t i = 0; i < 100; ++i) { 420f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org channel1()->SendData( 421d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org params, rtc::Buffer(&buffer[0], buffer.size()), &result); 422f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org if (result == cricket::SDR_BLOCK) 423f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org break; 424f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org } 425f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org 426f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org EXPECT_EQ(cricket::SDR_BLOCK, result); 427f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org} 428f7026cd7c84b7c10894972ba03d8d7b9c04a99f0jiayl@webrtc.org 429f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.orgTEST_F(SctpDataMediaChannelTest, ClosesRemoteStream) { 430f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SetupConnectedChannels(); 431f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SignalChannelClosedObserver chan_1_sig_receiver, chan_2_sig_receiver; 432f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org chan_1_sig_receiver.BindSelf(channel1()); 433f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org chan_2_sig_receiver.BindSelf(channel2()); 434f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 435f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org cricket::SendDataResult result; 436f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); 437f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 438f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); 439f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); 440f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 441f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); 442f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 443f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // Close channel 1. Channel 2 should notify us. 444f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel1()->RemoveSendStream(1); 445f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(chan_2_sig_receiver.WasStreamClosed(1), 1000); 446f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org} 447f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 448f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.orgTEST_F(SctpDataMediaChannelTest, ClosesTwoRemoteStreams) { 449f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SetupConnectedChannels(); 450f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org AddStream(3); 451f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SignalChannelClosedObserver chan_1_sig_receiver, chan_2_sig_receiver; 452f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org chan_1_sig_receiver.BindSelf(channel1()); 453f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org chan_2_sig_receiver.BindSelf(channel2()); 454f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 455f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org cricket::SendDataResult result; 456f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); 457f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 458f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); 459f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); 460f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 461f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); 462f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 463f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // Close two streams on one side. 464f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel2()->RemoveSendStream(2); 465f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel2()->RemoveSendStream(3); 466f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(2), 1000); 467f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(3), 1000); 468f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org} 469f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 470f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.orgTEST_F(SctpDataMediaChannelTest, ClosesStreamsOnBothSides) { 471f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SetupConnectedChannels(); 472f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org AddStream(3); 473f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org AddStream(4); 474f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SignalChannelClosedObserver chan_1_sig_receiver, chan_2_sig_receiver; 475f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org chan_1_sig_receiver.BindSelf(channel1()); 476f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org chan_2_sig_receiver.BindSelf(channel2()); 477f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 478f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org cricket::SendDataResult result; 479f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); 480f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 481f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); 482f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org ASSERT_TRUE(SendData(channel2(), 2, "hi chan1", &result)); 483f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 484f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver1(), 2, "hi chan1"), 1000); 485f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 486f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // Close one stream on channel1(), while closing three streams on 487f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // channel2(). They will conflict (only one side can close anything at a 488f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // time, apparently). Test the resolution of the conflict. 489f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel1()->RemoveSendStream(1); 490f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 491f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel2()->RemoveSendStream(2); 492f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel2()->RemoveSendStream(3); 493f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel2()->RemoveSendStream(4); 494f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(chan_2_sig_receiver.WasStreamClosed(1), 1000); 495f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(2), 1000); 496f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(3), 1000); 497f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(chan_1_sig_receiver.WasStreamClosed(4), 1000); 498f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org} 499f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 500e8386d21992b6683b6fadd315ea631875b4256fbLally SinghTEST_F(SctpDataMediaChannelTest, EngineSignalsRightChannel) { 501e8386d21992b6683b6fadd315ea631875b4256fbLally Singh SetupConnectedChannels(); 502e8386d21992b6683b6fadd315ea631875b4256fbLally Singh EXPECT_TRUE_WAIT(channel1()->socket() != NULL, 1000); 503e8386d21992b6683b6fadd315ea631875b4256fbLally Singh struct socket *sock = const_cast<struct socket*>(channel1()->socket()); 504e8386d21992b6683b6fadd315ea631875b4256fbLally Singh int prior_count = channel1_ready_to_send_count(); 505e8386d21992b6683b6fadd315ea631875b4256fbLally Singh cricket::SctpDataEngine::SendThresholdCallback(sock, 0); 506e8386d21992b6683b6fadd315ea631875b4256fbLally Singh EXPECT_GT(channel1_ready_to_send_count(), prior_count); 507e8386d21992b6683b6fadd315ea631875b4256fbLally Singh} 508e8386d21992b6683b6fadd315ea631875b4256fbLally Singh 50927ed3cc28cf950456a0c66d7a10656a96832feddlallyTEST_F(SctpDataMediaChannelTest, RefusesHighNumberedChannels) { 51027ed3cc28cf950456a0c66d7a10656a96832feddlally SetupConnectedChannels(); 51127ed3cc28cf950456a0c66d7a10656a96832feddlally EXPECT_TRUE(AddStream(1022)); 51227ed3cc28cf950456a0c66d7a10656a96832feddlally EXPECT_FALSE(AddStream(1023)); 51327ed3cc28cf950456a0c66d7a10656a96832feddlally} 51427ed3cc28cf950456a0c66d7a10656a96832feddlally 5150c2629973929d5585d310698fab1a1e21b39d5c9tina.legrand@webrtc.org// Flaky on Linux and Windows. See webrtc:4453. 5160c2629973929d5585d310698fab1a1e21b39d5c9tina.legrand@webrtc.org#if defined(WEBRTC_WIN) || defined(WEBRTC_LINUX) 5170c2629973929d5585d310698fab1a1e21b39d5c9tina.legrand@webrtc.org#define MAYBE_ReusesAStream DISABLED_ReusesAStream 5180c2629973929d5585d310698fab1a1e21b39d5c9tina.legrand@webrtc.org#else 5190c2629973929d5585d310698fab1a1e21b39d5c9tina.legrand@webrtc.org#define MAYBE_ReusesAStream ReusesAStream 5200c2629973929d5585d310698fab1a1e21b39d5c9tina.legrand@webrtc.org#endif 5210c2629973929d5585d310698fab1a1e21b39d5c9tina.legrand@webrtc.orgTEST_F(SctpDataMediaChannelTest, MAYBE_ReusesAStream) { 522f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // Shut down channel 1, then open it up again for reuse. 523f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SetupConnectedChannels(); 524f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org cricket::SendDataResult result; 525f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org SignalChannelClosedObserver chan_2_sig_receiver; 526f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org chan_2_sig_receiver.BindSelf(channel2()); 527f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 528f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org ASSERT_TRUE(SendData(channel1(), 1, "hello?", &result)); 529f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 530f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hello?"), 1000); 531f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 532f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel1()->RemoveSendStream(1); 533f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(chan_2_sig_receiver.WasStreamClosed(1), 1000); 534f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // Channel 1 is gone now. 535f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org 536f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // Create a new channel 1. 537f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org AddStream(1); 538f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org ASSERT_TRUE(SendData(channel1(), 1, "hi?", &result)); 539f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_EQ(cricket::SDR_SUCCESS, result); 540f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(ReceivedData(receiver2(), 1, "hi?"), 1000); 541f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org channel1()->RemoveSendStream(1); 542f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org EXPECT_TRUE_WAIT(chan_2_sig_receiver.StreamCloseCount(1) == 2, 1000); 543f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org} 544