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