15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/*
25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle
35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2004 Google Inc.
45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without
65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met:
75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer.
105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     this list of conditions and the following disclaimer in the documentation
125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     and/or other materials provided with the distribution.
135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *  3. The name of the author may not be used to endorse or promote products
145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *     derived from this software without specific prior written permission.
155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *
165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */
275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <cstring>
295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <sstream>
305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <deque>
315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <map>
325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/base64.h"
345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/common.h"
353a6035d31f360cb7a9420b7934176494b09721b3mallinath@webrtc.org#include "talk/base/dscp.h"
365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/gunit.h"
375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/helpers.h"
385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/logging.h"
395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/natserver.h"
405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/natsocketfactory.h"
415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/stringencode.h"
425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/basicpacketsocketfactory.h"
435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/constants.h"
445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/parsing.h"
455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/portallocator.h"
465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/p2ptransport.h"
475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/relayport.h"
485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/relayserver.h"
495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/session.h"
505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/sessionclient.h"
515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/sessionmanager.h"
525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/stunport.h"
535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/stunserver.h"
545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/transportchannel.h"
555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/transportchannelproxy.h"
565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/p2p/base/udpport.h"
575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/xmpp/constants.h"
585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing cricket::SignalingProtocol;
605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing cricket::PROTOCOL_HYBRID;
615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing cricket::PROTOCOL_JINGLE;
625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing cricket::PROTOCOL_GINGLE;
635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const std::string kInitiator = "init@init.com";
655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const std::string kResponder = "resp@resp.com";
665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Expected from test random number generator.
675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const std::string kSessionId = "9254631414740579489";
685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// TODO: When we need to test more than one transport type,
695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// allow this to be injected like the content types are.
705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const std::string kTransportType = "http://www.google.com/transport/p2p";
715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Controls how long we wait for a session to send messages that we
735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// expect, in milliseconds.  We put it high to avoid flaky tests.
745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kEventTimeout = 5000;
755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kNumPorts = 2;
775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kPort0 = 28653;
785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kPortStep = 5;
795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const std::string kNotifyNick1 = "derekcheng_google.com^59422C27";
815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const std::string kNotifyNick2 = "someoneelses_google.com^7abd6a7a20";
825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const uint32 kNotifyAudioSsrc1 = 2625839801U;
835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const uint32 kNotifyAudioSsrc2 = 2529430427U;
845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const uint32 kNotifyVideoSsrc1 = 3;
855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const uint32 kNotifyVideoSsrc2 = 2;
865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const std::string kViewRequestNick = "param_google.com^16A3CDBE";
885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const uint32 kViewRequestSsrc = 4;
895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kViewRequestWidth = 320;
905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kViewRequestHeight = 200;
915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic const int kViewRequestFrameRate = 15;
925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgint GetPort(int port_index) {
945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return kPort0 + (port_index * kPortStep);
955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GetPortString(int port_index) {
985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return talk_base::ToString(GetPort(port_index));
995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Only works for port_index < 10, which is fine for our purposes.
1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GetUsername(int port_index) {
1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "username" + std::string(8, talk_base::ToString(port_index)[0]);
1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Only works for port_index < 10, which is fine for our purposes.
1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GetPassword(int port_index) {
1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "password" + std::string(8, talk_base::ToString(port_index)[0]);
1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string IqAck(const std::string& id,
1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                  const std::string& from,
1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                  const std::string& to) {
1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<cli:iq"
1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " to=\"" + to + "\""
1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " id=\"" + id + "\""
1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " type=\"result\""
1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " from=\"" + from + "\""
1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns:cli=\"jabber:client\""
1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "/>";
1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string IqSet(const std::string& id,
1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                  const std::string& from,
1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                  const std::string& to,
1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                  const std::string& content) {
1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<cli:iq"
1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " to=\"" + to + "\""
1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " type=\"set\""
1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " from=\"" + from + "\""
1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " id=\"" + id + "\""
1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns:cli=\"jabber:client\""
1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      + content +
1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</cli:iq>";
1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string IqError(const std::string& id,
1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    const std::string& from,
1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    const std::string& to,
1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    const std::string& content) {
1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<cli:error"
1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " to=\"" + to + "\""
1445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " type=\"error\""
1455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " from=\"" + from + "\""
1465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " id=\"" + id + "\""
1475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns:cli=\"jabber:client\""
1485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
1495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      + content +
1505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</cli:error>";
1515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GingleSessionXml(const std::string& type,
1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             const std::string& content) {
1555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<session"
1565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns=\"http://www.google.com/session\""
1575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " type=\"" + type + "\""
1585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " id=\"" + kSessionId + "\""
1595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " initiator=\"" + kInitiator + "\""
1605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
1615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      + content +
1625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</session>";
1635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GingleDescriptionXml(const std::string& content_type) {
1665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<description"
1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns=\"" + content_type + "\""
1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "/>";
1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string P2pCandidateXml(const std::string& name, int port_index) {
1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Port will update the rtcp username by +1 on the last character. So we need
1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // to compensate here. See Port::username_fragment() for detail.
1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string username = GetUsername(port_index);
1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // TODO: Use the component id instead of the channel name to
1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // determinte if we need to covert the username here.
1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (name == "rtcp" || name == "video_rtcp" || name == "chanb") {
1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    char next_ch = username[username.size() - 1];
1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ASSERT(username.size() > 0);
1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::Base64::GetNextBase64Char(next_ch, &next_ch);
1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    username[username.size() - 1] = next_ch;
1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<candidate"
1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " name=\"" + name + "\""
1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " address=\"127.0.0.1\""
1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " port=\"" + GetPortString(port_index) + "\""
1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " preference=\"0.99\""
1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " username=\"" + username + "\""
1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " protocol=\"udp\""
1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " generation=\"0\""
1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " password=\"" + GetPassword(port_index) + "\""
1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " type=\"local\""
1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " network=\"network\""
1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "/>";
1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleActionXml(const std::string& action,
1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            const std::string& content) {
1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<jingle"
2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns=\"urn:xmpp:jingle:1\""
2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " action=\"" + action + "\""
2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " sid=\"" + kSessionId + "\""
2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      + content +
2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</jingle>";
2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleInitiateActionXml(const std::string& content) {
2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<jingle"
2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns=\"urn:xmpp:jingle:1\""
2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " action=\"session-initiate\""
2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " sid=\"" + kSessionId + "\""
2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " initiator=\"" + kInitiator + "\""
2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      + content +
2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</jingle>";
2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleGroupInfoXml(const std::string& content_name_a,
2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                               const std::string& content_name_b) {
2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string group_info = "<jin:group"
2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " type=\"BUNDLE\""
2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns:jin=\"google:jingle\""
2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">";
2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!content_name_a.empty())
2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    group_info += "<content name=\"" + content_name_a + "\""
2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "/>";
2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (!content_name_b.empty())
2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    group_info += "<content name=\"" + content_name_b + "\""
2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "/>";
2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  group_info += "</jin:group>";
2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return group_info;
2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleEmptyContentXml(const std::string& content_name,
2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                  const std::string& content_type,
2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                  const std::string& transport_type) {
2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<content"
2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " name=\"" + content_name + "\""
2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " creator=\"initiator\""
2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "<description"
2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns=\"" + content_type + "\""
2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "/>"
2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "<transport"
2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns=\"" + transport_type + "\""
2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "/>"
2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</content>";
2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleContentXml(const std::string& content_name,
2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             const std::string& content_type,
2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             const std::string& transport_type,
2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             const std::string& transport_main) {
2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string transport = transport_type.empty() ? "" :
2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "<transport"
2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns=\"" + transport_type + "\""
2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      + transport_main +
2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</transport>";
2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return"<content"
2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " name=\"" + content_name + "\""
2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " creator=\"initiator\""
2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "<description"
2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns=\"" + content_type + "\""
2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "/>"
2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      + transport +
2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</content>";
2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleTransportContentXml(const std::string& content_name,
2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                      const std::string& transport_type,
2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                      const std::string& content) {
2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "<content"
2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " name=\"" + content_name + "\""
2795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " creator=\"initiator\""
2805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
2815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "<transport"
2825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      " xmlns=\"" + transport_type + "\""
2835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ">"
2845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      + content +
2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</transport>"
2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "</content>";
2875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GingleInitiateXml(const std::string& content_type) {
2905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GingleSessionXml(
2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "initiate",
2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      GingleDescriptionXml(content_type));
2935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleInitiateXml(const std::string& content_name_a,
2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& content_type_a,
2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& content_name_b,
2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& content_type_b,
2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              bool bundle = false) {
3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string content_xml;
3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (content_name_b.empty()) {
3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    content_xml = JingleEmptyContentXml(
3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type_a, kTransportType);
3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  } else {
3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    content_xml = JingleEmptyContentXml(
3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org           content_name_a, content_type_a, kTransportType) +
3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org       JingleEmptyContentXml(
3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org           content_name_b, content_type_b, kTransportType);
3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (bundle) {
3105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      content_xml += JingleGroupInfoXml(content_name_a, content_name_b);
3115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
3125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return JingleInitiateActionXml(content_xml);
3145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GingleAcceptXml(const std::string& content_type) {
3175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GingleSessionXml(
3185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "accept",
3195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      GingleDescriptionXml(content_type));
3205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleAcceptXml(const std::string& content_name_a,
3235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            const std::string& content_type_a,
3245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            const std::string& content_name_b,
3255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            const std::string& content_type_b,
3265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            bool bundle = false) {
3275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string content_xml;
3285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (content_name_b.empty()) {
3295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    content_xml = JingleEmptyContentXml(
3305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type_a, kTransportType);
3315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  } else {
3325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    content_xml = JingleEmptyContentXml(
3335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type_a, kTransportType) +
3345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        JingleEmptyContentXml(
3355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org            content_name_b, content_type_b, kTransportType);
3365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (bundle) {
3385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    content_xml += JingleGroupInfoXml(content_name_a, content_name_b);
3395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
3405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return JingleActionXml("session-accept", content_xml);
3425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string Gingle2CandidatesXml(const std::string& channel_name,
3455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                 int port_index0,
3465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                 int port_index1) {
3475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GingleSessionXml(
3485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "candidates",
3495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      P2pCandidateXml(channel_name, port_index0) +
3505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      P2pCandidateXml(channel_name, port_index1));
3515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string Gingle4CandidatesXml(const std::string& channel_name_a,
3545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                 int port_index0,
3555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                 int port_index1,
3565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                 const std::string& channel_name_b,
3575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                 int port_index2,
3585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                 int port_index3) {
3595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GingleSessionXml(
3605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "candidates",
3615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      P2pCandidateXml(channel_name_a, port_index0) +
3625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      P2pCandidateXml(channel_name_a, port_index1) +
3635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      P2pCandidateXml(channel_name_b, port_index2) +
3645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      P2pCandidateXml(channel_name_b, port_index3));
3655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string Jingle2TransportInfoXml(const std::string& content_name,
3685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    const std::string& channel_name,
3695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    int port_index0,
3705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    int port_index1) {
3715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return JingleActionXml(
3725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "transport-info",
3735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      JingleTransportContentXml(
3745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          content_name, kTransportType,
3755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          P2pCandidateXml(channel_name, port_index0) +
3765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          P2pCandidateXml(channel_name, port_index1)));
3775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string Jingle4TransportInfoXml(const std::string& content_name,
3805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    const std::string& channel_name_a,
3815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    int port_index0,
3825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    int port_index1,
3835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    const std::string& channel_name_b,
3845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    int port_index2,
3855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                    int port_index3) {
3865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return JingleActionXml(
3875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "transport-info",
3885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      JingleTransportContentXml(
3895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          content_name, kTransportType,
3905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          P2pCandidateXml(channel_name_a, port_index0) +
3915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          P2pCandidateXml(channel_name_a, port_index1) +
3925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          P2pCandidateXml(channel_name_b, port_index2) +
3935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          P2pCandidateXml(channel_name_b, port_index3)));
3945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
3955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
3965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleDescriptionInfoXml(const std::string& content_name,
3975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                     const std::string& content_type) {
3985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return JingleActionXml(
3995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "description-info",
4005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      JingleContentXml(content_name, content_type, "", ""));
4015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
4025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GingleRejectXml(const std::string& reason) {
4045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GingleSessionXml(
4055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "reject",
4065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "<" + reason + "/>");
4075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
4085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleTerminateXml(const std::string& reason) {
4105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return JingleActionXml(
4115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        "session-terminate",
4125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        "<reason><" + reason + "/></reason>");
4135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
4145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GingleTerminateXml(const std::string& reason) {
4165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return GingleSessionXml(
4175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "terminate",
4185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      "<" + reason + "/>");
4195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
4205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string GingleRedirectXml(const std::string& intitiate,
4225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& target) {
4235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return intitiate +
4245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "<error code=\"302\" type=\"modify\">"
4255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "<redirect xmlns=\"http://www.google.com/session\">"
4265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "xmpp:" + target +
4275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "</redirect>"
4285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "</error>";
4295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
4305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string JingleRedirectXml(const std::string& intitiate,
4325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& target) {
4335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return intitiate +
4345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "<error code=\"302\" type=\"modify\">"
4355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "<redirect xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\">"
4365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "xmpp:" + target +
4375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "</redirect>"
4385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    "</error>";
4395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
4405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string InitiateXml(SignalingProtocol protocol,
4425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& gingle_content_type,
4435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& content_name_a,
4445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& content_type_a,
4455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& content_name_b,
4465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& content_type_b,
4475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        bool bundle = false) {
4485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  switch (protocol) {
4495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_JINGLE:
4505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return JingleInitiateXml(content_name_a, content_type_a,
4515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                               content_name_b, content_type_b,
4525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                               bundle);
4535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_GINGLE:
4545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return GingleInitiateXml(gingle_content_type);
4555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_HYBRID:
4565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return JingleInitiateXml(content_name_a, content_type_a,
4575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                               content_name_b, content_type_b) +
4585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          GingleInitiateXml(gingle_content_type);
4595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
4605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "";
4615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
4625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string InitiateXml(SignalingProtocol protocol,
4645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& content_name,
4655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& content_type) {
4665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return InitiateXml(protocol,
4675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     content_type,
4685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     content_name, content_type,
4695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     "", "");
4705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
4715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string AcceptXml(SignalingProtocol protocol,
4735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      const std::string& gingle_content_type,
4745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      const std::string& content_name_a,
4755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      const std::string& content_type_a,
4765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      const std::string& content_name_b,
4775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      const std::string& content_type_b,
4785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      bool bundle = false) {
4795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  switch (protocol) {
4805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_JINGLE:
4815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return JingleAcceptXml(content_name_a, content_type_a,
4825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             content_name_b, content_type_b, bundle);
4835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_GINGLE:
4845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return GingleAcceptXml(gingle_content_type);
4855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_HYBRID:
4865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return
4875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          JingleAcceptXml(content_name_a, content_type_a,
4885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                          content_name_b, content_type_b) +
4895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          GingleAcceptXml(gingle_content_type);
4905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
4915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "";
4925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
4935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
4955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string AcceptXml(SignalingProtocol protocol,
4965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      const std::string& content_name,
4975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      const std::string& content_type,
4985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      bool bundle = false) {
4995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return AcceptXml(protocol,
5005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   content_type,
5015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   content_name, content_type,
5025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   "", "");
5035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
5045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
5055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string TransportInfo2Xml(SignalingProtocol protocol,
5065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& content_name,
5075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& channel_name,
5085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              int port_index0,
5095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              int port_index1) {
5105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  switch (protocol) {
5115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_JINGLE:
5125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return Jingle2TransportInfoXml(
5135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          content_name,
5145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          channel_name, port_index0, port_index1);
5155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_GINGLE:
5165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return Gingle2CandidatesXml(
5175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          channel_name, port_index0, port_index1);
5185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_HYBRID:
5195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return
5205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          Jingle2TransportInfoXml(
5215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              content_name,
5225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              channel_name, port_index0, port_index1) +
5235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          Gingle2CandidatesXml(
5245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              channel_name, port_index0, port_index1);
5255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
5265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "";
5275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
5285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
5295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string TransportInfo4Xml(SignalingProtocol protocol,
5305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& content_name,
5315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& channel_name_a,
5325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              int port_index0,
5335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              int port_index1,
5345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              const std::string& channel_name_b,
5355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              int port_index2,
5365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              int port_index3) {
5375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  switch (protocol) {
5385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_JINGLE:
5395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return Jingle4TransportInfoXml(
5405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          content_name,
5415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          channel_name_a, port_index0, port_index1,
5425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          channel_name_b, port_index2, port_index3);
5435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_GINGLE:
5445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return Gingle4CandidatesXml(
5455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          channel_name_a, port_index0, port_index1,
5465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          channel_name_b, port_index2, port_index3);
5475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_HYBRID:
5485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return
5495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          Jingle4TransportInfoXml(
5505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              content_name,
5515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              channel_name_a, port_index0, port_index1,
5525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              channel_name_b, port_index2, port_index3) +
5535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          Gingle4CandidatesXml(
5545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              channel_name_a, port_index0, port_index1,
5555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              channel_name_b, port_index2, port_index3);
5565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
5575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "";
5585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
5595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
5605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string RejectXml(SignalingProtocol protocol,
5615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      const std::string& reason) {
5625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  switch (protocol) {
5635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_JINGLE:
5645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return JingleTerminateXml(reason);
5655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_GINGLE:
5665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return GingleRejectXml(reason);
5675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_HYBRID:
5685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return JingleTerminateXml(reason) +
5695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          GingleRejectXml(reason);
5705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
5715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "";
5725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
5735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
5745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string TerminateXml(SignalingProtocol protocol,
5755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                         const std::string& reason) {
5765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  switch (protocol) {
5775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_JINGLE:
5785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return JingleTerminateXml(reason);
5795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_GINGLE:
5805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return GingleTerminateXml(reason);
5815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_HYBRID:
5825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return JingleTerminateXml(reason) +
5835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          GingleTerminateXml(reason);
5845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
5855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "";
5865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
5875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
5885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string RedirectXml(SignalingProtocol protocol,
5895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& initiate,
5905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        const std::string& target) {
5915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  switch (protocol) {
5925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_JINGLE:
5935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return JingleRedirectXml(initiate, target);
5945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    case PROTOCOL_GINGLE:
5955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return GingleRedirectXml(initiate, target);
5965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    default:
5975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      break;
5985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
5995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return "";
6005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
6015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// TODO: Break out and join with fakeportallocator.h
6035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass TestPortAllocatorSession : public cricket::PortAllocatorSession {
6045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
6055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestPortAllocatorSession(const std::string& content_name,
6065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                           int component,
6075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                           const std::string& ice_ufrag,
6085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                           const std::string& ice_pwd,
6095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                           const int port_offset)
6105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      : PortAllocatorSession(content_name, component, ice_ufrag, ice_pwd, 0),
6115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        port_offset_(port_offset),
6125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        ports_(kNumPorts),
6135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        address_("127.0.0.1", 0),
6145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        network_("network", "unittest",
6155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 talk_base::IPAddress(INADDR_LOOPBACK), 8),
6165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        socket_factory_(talk_base::Thread::Current()),
6175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        running_(false),
6185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        port_(28653) {
6195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    network_.AddIP(address_.ipaddr());
6205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
6215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ~TestPortAllocatorSession() {
6235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    for (size_t i = 0; i < ports_.size(); i++)
6245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      delete ports_[i];
6255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
6265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void StartGettingPorts() {
6285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    for (int i = 0; i < kNumPorts; i++) {
6295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      int index = port_offset_ + i;
6305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      ports_[i] = cricket::UDPPort::Create(
6315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          talk_base::Thread::Current(), &socket_factory_,
6325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          &network_, address_.ipaddr(), GetPort(index), GetPort(index),
6335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          GetUsername(index), GetPassword(index));
6345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      AddPort(ports_[i]);
6355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
6365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    running_ = true;
6375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
6385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void StopGettingPorts() { running_ = false; }
6405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual bool IsGettingPorts() { return running_; }
6415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void AddPort(cricket::Port* port) {
6435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    port->set_component(component_);
6445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    port->set_generation(0);
6455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    port->SignalDestroyed.connect(
6465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        this, &TestPortAllocatorSession::OnPortDestroyed);
6475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    port->SignalPortComplete.connect(
6485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        this, &TestPortAllocatorSession::OnPortComplete);
6495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    port->PrepareAddress();
6505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalPortReady(this, port);
6515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
6525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnPortDestroyed(cricket::PortInterface* port) {
6545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    for (size_t i = 0; i < ports_.size(); i++) {
6555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      if (ports_[i] == port)
6565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        ports_[i] = NULL;
6575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
6585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
6595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnPortComplete(cricket::Port* port) {
6615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalCandidatesReady(this, port->Candidates());
6625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
6635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private:
6655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int port_offset_;
6665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::vector<cricket::Port*> ports_;
6675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::SocketAddress address_;
6685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::Network network_;
6695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  talk_base::BasicPacketSocketFactory socket_factory_;
6705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool running_;
6715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int port_;
6725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
6735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass TestPortAllocator : public cricket::PortAllocator {
6755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
6765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestPortAllocator() : port_offset_(0) {}
6775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual cricket::PortAllocatorSession*
6795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  CreateSessionInternal(
6805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                const std::string& content_name,
6815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                int component,
6825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                const std::string& ice_ufrag,
6835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                const std::string& ice_pwd) {
6845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    port_offset_ += 2;
6855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return new TestPortAllocatorSession(content_name, component,
6865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                        ice_ufrag, ice_pwd, port_offset_ - 2);
6875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
6885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int port_offset_;
6905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
6915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
6925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass TestContentDescription : public cricket::ContentDescription {
6935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
6945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  explicit TestContentDescription(const std::string& gingle_content_type,
6955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                  const std::string& content_type)
6965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      : gingle_content_type(gingle_content_type),
6975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_type(content_type) {
6985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
6995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual ContentDescription* Copy() const {
7005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return new TestContentDescription(*this);
7015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
7025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string gingle_content_type;
7045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string content_type;
7055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
7065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgcricket::SessionDescription* NewTestSessionDescription(
7085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::string gingle_content_type,
7095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::string& content_name_a, const std::string& content_type_a,
7105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::string& content_name_b, const std::string& content_type_b) {
7115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::SessionDescription* offer = new cricket::SessionDescription();
7135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  offer->AddContent(content_name_a, content_type_a,
7145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    new TestContentDescription(gingle_content_type,
7155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                               content_type_a));
7165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::TransportDescription desc(cricket::NS_GINGLE_P2P,
717b17e4d000599d5caf286d9599cc5244410e1f313sergeyu@chromium.org                                     std::string(), std::string());
7185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  offer->AddTransportInfo(cricket::TransportInfo(content_name_a, desc));
7195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  if (content_name_a != content_name_b) {
7215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    offer->AddContent(content_name_b, content_type_b,
7225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      new TestContentDescription(gingle_content_type,
7235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                                 content_type_b));
7245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    offer->AddTransportInfo(cricket::TransportInfo(content_name_b, desc));
7255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
7265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return offer;
7275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
7285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgcricket::SessionDescription* NewTestSessionDescription(
7305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const std::string& content_name, const std::string& content_type) {
7315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::SessionDescription* offer = new cricket::SessionDescription();
7335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  offer->AddContent(content_name, content_type,
7345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    new TestContentDescription(content_type,
7355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                               content_type));
7365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  offer->AddTransportInfo(cricket::TransportInfo
7375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                          (content_name, cricket::TransportDescription(
7385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                          cricket::NS_GINGLE_P2P,
739b17e4d000599d5caf286d9599cc5244410e1f313sergeyu@chromium.org                          std::string(), std::string())));
7405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  return offer;
7415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
7425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstruct TestSessionClient: public cricket::SessionClient,
7445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                          public sigslot::has_slots<> {
7455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
7465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestSessionClient() {
7475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
7485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ~TestSessionClient() {
7505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
7515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual bool ParseContent(SignalingProtocol protocol,
7535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            const buzz::XmlElement* elem,
7545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            cricket::ContentDescription** content,
7555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            cricket::ParseError* error) {
7565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type;
7575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string gingle_content_type;
7585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (protocol == PROTOCOL_GINGLE) {
7595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      gingle_content_type = elem->Name().Namespace();
7605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else {
7615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      content_type = elem->Name().Namespace();
7625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
7635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    *content = new TestContentDescription(gingle_content_type, content_type);
7655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return true;
7665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
7675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual bool WriteContent(SignalingProtocol protocol,
7695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            const cricket::ContentDescription* untyped_content,
7705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            buzz::XmlElement** elem,
7715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                            cricket::WriteError* error) {
7725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const TestContentDescription* content =
7735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        static_cast<const TestContentDescription*>(untyped_content);
7745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = (protocol == PROTOCOL_GINGLE ?
7755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                content->gingle_content_type :
7765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                content->content_type);
7775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org     *elem = new buzz::XmlElement(
7785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        buzz::QName(content_type, "description"), true);
7795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return true;
7805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
7815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnSessionCreate(cricket::Session* session, bool initiate) {
7835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
7845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnSessionDestroy(cricket::Session* session) {
7865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
7875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
7885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstruct ChannelHandler : sigslot::has_slots<> {
7905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  explicit ChannelHandler(cricket::TransportChannel* p, const std::string& name)
7915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    : channel(p), last_readable(false), last_writable(false), data_count(0),
7925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      last_size(0), name(name) {
7935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    p->SignalReadableState.connect(this, &ChannelHandler::OnReadableState);
7945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    p->SignalWritableState.connect(this, &ChannelHandler::OnWritableState);
7955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    p->SignalReadPacket.connect(this, &ChannelHandler::OnReadPacket);
7965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
7975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
7985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool writable() const {
7995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return last_writable && channel->writable();
8005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
8015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool readable() const {
8035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return last_readable && channel->readable();
8045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
8055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnReadableState(cricket::TransportChannel* p) {
8075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(channel, p);
8085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_readable = channel->readable();
8095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
8105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnWritableState(cricket::TransportChannel* p) {
8125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(channel, p);
8135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_writable = channel->writable();
8145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
8155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnReadPacket(cricket::TransportChannel* p, const char* buf,
817d3ecbb30dc2684653d61e8ec88a5382aecf62773wu@webrtc.org                    size_t size, const talk_base::PacketTime& time, int flags) {
8185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (memcmp(buf, name.c_str(), name.size()) != 0)
8195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      return;  // drop packet if packet doesn't belong to this channel. This
8205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               // can happen when transport channels are muxed together.
8215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    buf += name.size();  // Remove channel name from the message.
8225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    size -= name.size();  // Decrement size by channel name string size.
8235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(channel, p);
8245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_LE(size, sizeof(last_data));
8255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    data_count += 1;
8265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_size = size;
8275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::memcpy(last_data, buf, size);
8285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
8295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void Send(const char* data, size_t size) {
8315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string data_with_id(name);
8325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    data_with_id += data;
8335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int result = channel->SendPacket(data_with_id.c_str(), data_with_id.size(),
8343a6035d31f360cb7a9420b7934176494b09721b3mallinath@webrtc.org                                     talk_base::DSCP_NO_CHANGE, 0);
8355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(static_cast<int>(data_with_id.size()), result);
8365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
8375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::TransportChannel* channel;
8395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool last_readable, last_writable;
8405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int data_count;
8415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  char last_data[4096];
8425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  size_t last_size;
8435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string name;
8445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
8455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid PrintStanza(const std::string& message,
8475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 const buzz::XmlElement* stanza) {
8485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  printf("%s: %s\n", message.c_str(), stanza->Str().c_str());
8495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
8505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass TestClient : public sigslot::has_slots<> {
8525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public:
8535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // TODO: Add channel_component_a/b as inputs to the ctor.
8545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestClient(cricket::PortAllocator* port_allocator,
8555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org             int* next_message_id,
8565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org             const std::string& local_name,
8575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org             SignalingProtocol start_protocol,
8585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org             const std::string& content_type,
8595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org             const std::string& content_name_a,
8605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org             const std::string& channel_name_a,
8615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org             const std::string& content_name_b,
8625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org             const std::string& channel_name_b) {
8635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    Construct(port_allocator, next_message_id, local_name, start_protocol,
8645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              content_type, content_name_a, channel_name_a,
8655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              content_name_b, channel_name_b);
8665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
8675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  ~TestClient() {
8695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (session) {
8705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      session_manager->DestroySession(session);
8715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(1U, session_destroyed_count);
8725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
8735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    delete session_manager;
8745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    delete client;
875c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org    for (std::deque<buzz::XmlElement*>::iterator it = sent_stanzas.begin();
876c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org         it != sent_stanzas.end(); ++it) {
877c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org      delete *it;
878c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org    }
8795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
8805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
8815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void Construct(cricket::PortAllocator* pa,
8825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 int* message_id,
8835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 const std::string& lname,
8845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 SignalingProtocol protocol,
8855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 const std::string& cont_type,
8865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 const std::string& cont_name_a,
8875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 const std::string& chan_name_a,
8885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 const std::string& cont_name_b,
8895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                 const std::string& chan_name_b) {
8905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    port_allocator_ = pa;
8915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    next_message_id = message_id;
8925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    local_name = lname;
8935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    start_protocol = protocol;
8945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    content_type = cont_type;
8955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    content_name_a = cont_name_a;
8965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    channel_name_a = chan_name_a;
8975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    content_name_b = cont_name_b;
8985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    channel_name_b = chan_name_b;
8995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_created_count = 0;
9005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_destroyed_count = 0;
9015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_remote_description_update_count = 0;
9025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    new_local_description = false;
9035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    new_remote_description = false;
9045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_content_action = cricket::CA_OFFER;
9055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_content_source = cricket::CS_LOCAL;
9065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session = NULL;
9075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_session_state = cricket::BaseSession::STATE_INIT;
9085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    blow_up_on_error = true;
9095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    error_count = 0;
9105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager = new cricket::SessionManager(port_allocator_);
9125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager->SignalSessionCreate.connect(
9135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        this, &TestClient::OnSessionCreate);
9145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager->SignalSessionDestroy.connect(
9155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        this, &TestClient::OnSessionDestroy);
9165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager->SignalOutgoingMessage.connect(
9175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        this, &TestClient::OnOutgoingMessage);
9185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    client = new TestSessionClient();
9205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager->AddClient(content_type, client);
9215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(client, session_manager->GetClient(content_type));
9225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  uint32 sent_stanza_count() const {
925b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org    return static_cast<uint32>(sent_stanzas.size());
9265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  const buzz::XmlElement* stanza() const {
929c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org    return last_expected_sent_stanza.get();
9305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::BaseSession::State session_state() const {
9335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(last_session_state, session->state());
9345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return session->state();
9355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void SetSessionState(cricket::BaseSession::State state) {
9385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session->SetState(state);
9395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ_WAIT(last_session_state, session->state(), kEventTimeout);
9405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void CreateSession() {
9435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager->CreateSession(local_name, content_type);
9445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void DeliverStanza(const buzz::XmlElement* stanza) {
9475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager->OnIncomingMessage(stanza);
9485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void DeliverStanza(const std::string& str) {
9515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    buzz::XmlElement* stanza = buzz::XmlElement::ForStr(str);
9525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager->OnIncomingMessage(stanza);
9535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    delete stanza;
9545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void DeliverAckToLastStanza() {
9575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const buzz::XmlElement* orig_stanza = stanza();
9585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const buzz::XmlElement* response_stanza =
9595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        buzz::XmlElement::ForStr(IqAck(orig_stanza->Attr(buzz::QN_IQ), "", ""));
9605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager->OnIncomingResponse(orig_stanza, response_stanza);
9615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    delete response_stanza;
9625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void ExpectSentStanza(const std::string& expected) {
9655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(!sent_stanzas.empty()) <<
9665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        "Found no stanza when expected " << expected;
9675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
968c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org    last_expected_sent_stanza.reset(sent_stanzas.front());
9695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    sent_stanzas.pop_front();
9705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string actual = last_expected_sent_stanza->Str();
9725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(expected, actual);
9735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void SkipUnsentStanza() {
9765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    GetNextOutgoingMessageID();
9775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool HasTransport(const std::string& content_name) const {
9805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ASSERT(session != NULL);
9815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const cricket::Transport* transport = session->GetTransport(content_name);
9825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return transport != NULL && (kTransportType == transport->type());
9835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool HasChannel(const std::string& content_name,
9865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                  int component) const {
9875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ASSERT(session != NULL);
9885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const cricket::TransportChannel* channel =
9895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        session->GetChannel(content_name, component);
9905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return channel != NULL && (component == channel->component());
9915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::TransportChannel* GetChannel(const std::string& content_name,
9945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                        int component) const {
9955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ASSERT(session != NULL);
9965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return session->GetChannel(content_name, component);
9975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
9985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
9995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnSessionCreate(cricket::Session* created_session, bool initiate) {
10005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_created_count += 1;
10015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session = created_session;
10035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session->set_current_protocol(start_protocol);
10045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session->SignalState.connect(this, &TestClient::OnSessionState);
10055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session->SignalError.connect(this, &TestClient::OnSessionError);
10065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session->SignalRemoteDescriptionUpdate.connect(
10075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        this, &TestClient::OnSessionRemoteDescriptionUpdate);
10085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session->SignalNewLocalDescription.connect(
10095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        this, &TestClient::OnNewLocalDescription);
10105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session->SignalNewRemoteDescription.connect(
10115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        this, &TestClient::OnNewRemoteDescription);
10125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    CreateChannels();
10145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnSessionDestroy(cricket::Session *session) {
10175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_destroyed_count += 1;
10185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnSessionState(cricket::BaseSession* session,
10215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      cricket::BaseSession::State state) {
10225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // EXPECT_EQ does not allow use of this, hence the tmp variable.
10235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::BaseSession* tmp = this->session;
10245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(tmp, session);
10255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_session_state = state;
10265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnSessionError(cricket::BaseSession* session,
10295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                      cricket::BaseSession::Error error) {
10305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // EXPECT_EQ does not allow use of this, hence the tmp variable.
10315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::BaseSession* tmp = this->session;
10325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(tmp, session);
10335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (blow_up_on_error) {
10345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(false);
10355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else {
10365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      error_count++;
10375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
10385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnSessionRemoteDescriptionUpdate(cricket::BaseSession* session,
10415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::ContentInfos& contents) {
10425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_remote_description_update_count++;
10435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnNewLocalDescription(cricket::BaseSession* session,
10465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                             cricket::ContentAction action) {
10475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    new_local_description = true;
10485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_content_action = action;
10495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_content_source = cricket::CS_LOCAL;
10505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnNewRemoteDescription(cricket::BaseSession* session,
10535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                              cricket::ContentAction action) {
10545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    new_remote_description = true;
10555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_content_action = action;
10565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    last_content_source = cricket::CS_REMOTE;
10575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void PrepareCandidates() {
10605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    session_manager->OnSignalingReady();
10615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void OnOutgoingMessage(cricket::SessionManager* manager,
10645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                         const buzz::XmlElement* stanza) {
10655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    buzz::XmlElement* elem = new buzz::XmlElement(*stanza);
10665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(elem->Name() == buzz::QN_IQ);
10675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(elem->HasAttr(buzz::QN_TO));
10685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_FALSE(elem->HasAttr(buzz::QN_FROM));
10695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(elem->HasAttr(buzz::QN_TYPE));
10705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE((elem->Attr(buzz::QN_TYPE) == "set") ||
10715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                (elem->Attr(buzz::QN_TYPE) == "result") ||
10725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                (elem->Attr(buzz::QN_TYPE) == "error"));
10735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    elem->SetAttr(buzz::QN_FROM, local_name);
10755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (elem->Attr(buzz::QN_TYPE) == "set") {
10765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_FALSE(elem->HasAttr(buzz::QN_ID));
10775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      elem->SetAttr(buzz::QN_ID, GetNextOutgoingMessageID());
10785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
10795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Uncommenting this is useful for debugging.
10815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // PrintStanza("OutgoingMessage", elem);
10825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    sent_stanzas.push_back(elem);
10835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string GetNextOutgoingMessageID() {
10865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int message_id = (*next_message_id)++;
10875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::ostringstream ost;
10885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ost << message_id;
10895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    return ost.str();
10905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
10915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
10925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void CreateChannels() {
10935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    ASSERT(session != NULL);
10945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // We either have a single content with multiple components (RTP/RTCP), or
10955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // multiple contents with single components, but not both.
10965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int component_a = 1;
10975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int component_b = (content_name_a == content_name_b) ? 2 : 1;
1098c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org    chan_a.reset(new ChannelHandler(
10995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        session->CreateChannel(content_name_a, channel_name_a, component_a),
1100c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org        channel_name_a));
1101c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org    chan_b.reset(new ChannelHandler(
11025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        session->CreateChannel(content_name_b, channel_name_b, component_b),
1103c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org        channel_name_b));
11045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
11055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int* next_message_id;
11075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string local_name;
11085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  SignalingProtocol start_protocol;
11095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string content_type;
11105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string content_name_a;
11115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string channel_name_a;
11125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string content_name_b;
11135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::string channel_name_b;
11145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  uint32 session_created_count;
11165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  uint32 session_destroyed_count;
11175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  uint32 session_remote_description_update_count;
11185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool new_local_description;
11195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool new_remote_description;
11205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::ContentAction last_content_action;
11215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::ContentSource last_content_source;
11225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  std::deque<buzz::XmlElement*> sent_stanzas;
1123c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org  talk_base::scoped_ptr<buzz::XmlElement> last_expected_sent_stanza;
11245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::SessionManager* session_manager;
11265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestSessionClient* client;
11275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::PortAllocator* port_allocator_;
11285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::Session* session;
11295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  cricket::BaseSession::State last_session_state;
1130c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org  talk_base::scoped_ptr<ChannelHandler> chan_a;
1131c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org  talk_base::scoped_ptr<ChannelHandler> chan_b;
11325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  bool blow_up_on_error;
11335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  int error_count;
11345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
11355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass SessionTest : public testing::Test {
11375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org protected:
11385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void SetUp() {
11395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Seed needed for each test to satisfy expectations.
11405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::SetRandomTestMode(true);
11415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
11425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  virtual void TearDown() {
11445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::SetRandomTestMode(false);
11455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
11465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Tests sending data between two clients, over two channels.
11485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestSendRecv(ChannelHandler* chan1a,
11495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    ChannelHandler* chan1b,
11505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    ChannelHandler* chan2a,
11515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    ChannelHandler* chan2b) {
11525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const char* dat1a = "spamspamspamspamspamspamspambakedbeansspam";
11535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const char* dat2a = "mapssnaebdekabmapsmapsmapsmapsmapsmapsmaps";
11545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const char* dat1b = "Lobster Thermidor a Crevette with a mornay sauce...";
11555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const char* dat2b = "...ecuas yanrom a htiw etteverC a rodimrehT retsboL";
11565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    for (int i = 0; i < 20; i++) {
11585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      chan1a->Send(dat1a, strlen(dat1a));
11595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      chan1b->Send(dat1b, strlen(dat1b));
11605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      chan2a->Send(dat2a, strlen(dat2a));
11615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      chan2b->Send(dat2b, strlen(dat2b));
11625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ_WAIT(i + 1, chan1a->data_count, kEventTimeout);
11645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ_WAIT(i + 1, chan1b->data_count, kEventTimeout);
11655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ_WAIT(i + 1, chan2a->data_count, kEventTimeout);
11665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ_WAIT(i + 1, chan2b->data_count, kEventTimeout);
11675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(strlen(dat2a), chan1a->last_size);
11695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(strlen(dat2b), chan1b->last_size);
11705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(strlen(dat1a), chan2a->last_size);
11715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(strlen(dat1b), chan2b->last_size);
11725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0, std::memcmp(chan1a->last_data, dat2a,
11745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                               strlen(dat2a)));
11755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0, std::memcmp(chan1b->last_data, dat2b,
11765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                               strlen(dat2b)));
11775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0, std::memcmp(chan2a->last_data, dat1a,
11785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                               strlen(dat1a)));
11795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0, std::memcmp(chan2b->last_data, dat1b,
11805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                               strlen(dat1b)));
11815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
11825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
11835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
11845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Test an initiate from one client to another, each with
11855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // independent initial protocols.  Checks for the correct initiates,
11865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // candidates, and accept messages, and tests that working network
11875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // channels are established.
11885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestSession(SignalingProtocol initiator_protocol,
11895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   SignalingProtocol responder_protocol,
11905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   SignalingProtocol resulting_protocol,
11915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& gingle_content_type,
11925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& content_type,
11935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& content_name_a,
11945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& channel_name_a,
11955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& content_name_b,
11965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& channel_name_b,
11975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& initiate_xml,
11985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& transport_info_a_xml,
11995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& transport_info_b_xml,
12005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& transport_info_reply_a_xml,
12015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& transport_info_reply_b_xml,
12025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   const std::string& accept_xml,
12035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   bool bundle = false) {
12045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
12055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
12065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
12075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
12095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
12105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, initiator_protocol,
12115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
12125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name_a,  channel_name_a,
12135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name_b,  channel_name_b));
12145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> responder(
12155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
12165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kResponder, responder_protocol,
12175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
12185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name_a,  channel_name_a,
12195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name_b,  channel_name_b));
12205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Create Session and check channels and state.
12225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
12235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(1U, initiator->session_created_count);
12245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(kSessionId, initiator->session->id());
12255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->local_name(), kInitiator);
12265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_INIT,
12275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
12285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // See comment in CreateChannels about how we choose component IDs.
12305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int component_a = 1;
12315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int component_b = (content_name_a == content_name_b) ? 2 : 1;
12325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasTransport(content_name_a));
12335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasChannel(content_name_a, component_a));
12345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasTransport(content_name_b));
12355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasChannel(content_name_b, component_b));
12365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Initiate and expect initiate message sent.
12385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SessionDescription* offer = NewTestSessionDescription(
12395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        gingle_content_type,
12405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type,
12415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_b, content_type);
12425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (bundle) {
12435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::ContentGroup group(cricket::GROUP_TYPE_BUNDLE);
12445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      group.AddContentName(content_name_a);
12455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      group.AddContentName(content_name_b);
12465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(group.HasContentName(content_name_a));
12475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(group.HasContentName(content_name_b));
12485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      offer->AddGroup(group);
12495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
12505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
12515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->remote_name(), kResponder);
12525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->local_description(), offer);
12535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
12555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
12565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
12575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
12595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("0", kInitiator, kResponder, initiate_xml));
12605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Deliver the initiate. Expect ack and session created with
12625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // transports.
12635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->DeliverStanza(initiator->stanza());
12645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
12655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("0", kResponder, kInitiator));
12665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, responder->sent_stanza_count());
12675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(1U, responder->session_created_count);
12695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(kSessionId, responder->session->id());
12705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(responder->session->local_name(), kResponder);
12715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(responder->session->remote_name(), kInitiator);
12725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
12735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              responder->session_state());
12745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasTransport(content_name_a));
12765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasChannel(content_name_a, component_a));
12775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasTransport(content_name_b));
12785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasChannel(content_name_b, component_b));
12795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Expect transport-info message from initiator.
12815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // But don't send candidates until initiate ack is received.
12825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->PrepareCandidates();
12835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    WAIT(initiator->sent_stanza_count() > 0, 100);
12845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, initiator->sent_stanza_count());
12855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverAckToLastStanza();
12865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
12875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
12885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("1", kInitiator, kResponder, transport_info_a_xml));
12895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Deliver transport-info and expect ack.
12915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->DeliverStanza(initiator->stanza());
12925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
12935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("1", kResponder, kInitiator));
12945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
12955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!transport_info_b_xml.empty()) {
12965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // Expect second transport-info message from initiator.
12975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
12985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      initiator->ExpectSentStanza(
12995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          IqSet("2", kInitiator, kResponder, transport_info_b_xml));
13005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0U, initiator->sent_stanza_count());
13015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // Deliver second transport-info message and expect ack.
13035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      responder->DeliverStanza(initiator->stanza());
13045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      responder->ExpectSentStanza(
13055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          IqAck("2", kResponder, kInitiator));
13065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else {
13075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0U, initiator->sent_stanza_count());
13085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0U, responder->sent_stanza_count());
13095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      initiator->SkipUnsentStanza();
13105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
13115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Expect reply transport-info message from responder.
13135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->PrepareCandidates();
13145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
13155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
13165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("3", kResponder, kInitiator, transport_info_reply_a_xml));
13175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Deliver reply transport-info and expect ack.
13195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverStanza(responder->stanza());
13205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
13215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("3", kInitiator, kResponder));
13225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (!transport_info_reply_b_xml.empty()) {
13245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // Expect second reply transport-info message from responder.
13255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
13265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      responder->ExpectSentStanza(
13275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          IqSet("4", kResponder, kInitiator, transport_info_reply_b_xml));
13285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0U, responder->sent_stanza_count());
13295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // Deliver second reply transport-info message and expect ack.
13315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      initiator->DeliverStanza(responder->stanza());
13325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      initiator->ExpectSentStanza(
13335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          IqAck("4", kInitiator, kResponder));
13345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0U, initiator->sent_stanza_count());
13355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else {
13365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0U, initiator->sent_stanza_count());
13375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0U, responder->sent_stanza_count());
13385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      responder->SkipUnsentStanza();
13395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
13405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // The channels should be able to become writable at this point.  This
13425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // requires pinging, so it may take a little while.
13435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->chan_a->writable() &&
13445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     initiator->chan_a->readable(), kEventTimeout);
13455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->chan_b->writable() &&
13465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     initiator->chan_b->readable(), kEventTimeout);
13475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(responder->chan_a->writable() &&
13485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     responder->chan_a->readable(), kEventTimeout);
13495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(responder->chan_b->writable() &&
13505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     responder->chan_b->readable(), kEventTimeout);
13515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Accept the session and expect accept stanza.
13535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SessionDescription* answer = NewTestSessionDescription(
13545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        gingle_content_type,
13555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type,
13565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_b, content_type);
13575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (bundle) {
13585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::ContentGroup group(cricket::GROUP_TYPE_BUNDLE);
13595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      group.AddContentName(content_name_a);
13605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      group.AddContentName(content_name_b);
13615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(group.HasContentName(content_name_a));
13625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(group.HasContentName(content_name_b));
13635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      answer->AddGroup(group);
13645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
13655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->session->Accept(answer));
13665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(responder->session->local_description(), answer);
13675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
13695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("5", kResponder, kInitiator, accept_xml));
13705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, responder->sent_stanza_count());
13725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Deliver the accept message and expect an ack.
13745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverStanza(responder->stanza());
13755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
13765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
13775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("5", kInitiator, kResponder));
13785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, initiator->sent_stanza_count());
13795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Both sessions should be in progress and have functioning
13815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // channels.
13825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(resulting_protocol, initiator->session->current_protocol());
13835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(resulting_protocol, responder->session->current_protocol());
13845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
13855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   initiator->session_state(), kEventTimeout);
13865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
13875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   responder->session_state(), kEventTimeout);
13885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (bundle) {
13895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::TransportChannel* initiator_chan_a = initiator->chan_a->channel;
13905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::TransportChannel* initiator_chan_b = initiator->chan_b->channel;
13915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
13925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // Since we know these are TransportChannelProxy, type cast it.
13935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::TransportChannelProxy* initiator_proxy_chan_a =
13945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          static_cast<cricket::TransportChannelProxy*>(initiator_chan_a);
13955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::TransportChannelProxy* initiator_proxy_chan_b =
13965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              static_cast<cricket::TransportChannelProxy*>(initiator_chan_b);
13975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(initiator_proxy_chan_a->impl() != NULL);
13985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(initiator_proxy_chan_b->impl() != NULL);
13995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(initiator_proxy_chan_a->impl(), initiator_proxy_chan_b->impl());
14005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::TransportChannel* responder_chan_a = responder->chan_a->channel;
14025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::TransportChannel* responder_chan_b = responder->chan_b->channel;
14035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // Since we know these are TransportChannelProxy, type cast it.
14055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::TransportChannelProxy* responder_proxy_chan_a =
14065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          static_cast<cricket::TransportChannelProxy*>(responder_chan_a);
14075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::TransportChannelProxy* responder_proxy_chan_b =
14085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              static_cast<cricket::TransportChannelProxy*>(responder_chan_b);
14095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(responder_proxy_chan_a->impl() != NULL);
14105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(responder_proxy_chan_b->impl() != NULL);
14115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(responder_proxy_chan_a->impl(), responder_proxy_chan_b->impl());
14125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
1413c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org    TestSendRecv(initiator->chan_a.get(), initiator->chan_b.get(),
1414c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org                 responder->chan_a.get(), responder->chan_b.get());
14155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (resulting_protocol == PROTOCOL_JINGLE) {
14175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // Deliver a description-info message to the initiator and check if the
14185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // content description changes.
14195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0U, initiator->session_remote_description_update_count);
14205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::SessionDescription* old_session_desc =
14225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          initiator->session->remote_description();
14235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::ContentInfo* old_content_a =
14245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          old_session_desc->GetContentByName(content_name_a);
14255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::ContentDescription* old_content_desc_a =
14265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          old_content_a->description;
14275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::ContentInfo* old_content_b =
14285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          old_session_desc->GetContentByName(content_name_b);
14295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::ContentDescription* old_content_desc_b =
14305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          old_content_b->description;
14315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(old_content_desc_a != NULL);
14325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(old_content_desc_b != NULL);
14335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      LOG(LS_INFO) << "A " << old_content_a->name;
14355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      LOG(LS_INFO) << "B " << old_content_b->name;
14365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      std::string description_info_xml =
14385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          JingleDescriptionInfoXml(content_name_a, content_type);
14395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      initiator->DeliverStanza(
14405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          IqSet("6", kResponder, kInitiator, description_info_xml));
14415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      responder->SkipUnsentStanza();
14425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(1U, initiator->session_remote_description_update_count);
14435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::SessionDescription* new_session_desc =
14455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          initiator->session->remote_description();
14465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::ContentInfo* new_content_a =
14475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          new_session_desc->GetContentByName(content_name_a);
14485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::ContentDescription* new_content_desc_a =
14495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          new_content_a->description;
14505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::ContentInfo* new_content_b =
14515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          new_session_desc->GetContentByName(content_name_b);
14525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      const cricket::ContentDescription* new_content_desc_b =
14535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          new_content_b->description;
14545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(new_content_desc_a != NULL);
14555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE(new_content_desc_b != NULL);
14565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // TODO: We used to replace contents from an update, but
14585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // that no longer works with partial updates.  We need to figure out
14595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // a way to merge patial updates into contents.  For now, users of
14605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // Session should listen to SignalRemoteDescriptionUpdate and handle
14615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // updates.  They should not expect remote_description to be the
14625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // latest value.
14635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // See session.cc OnDescriptionInfoMessage.
14645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // EXPECT_NE(old_content_desc_a, new_content_desc_a);
14665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // if (content_name_a != content_name_b) {
14685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      //   // If content_name_a != content_name_b, then b's content description
14695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      //   // should not have changed since the description-info message only
14705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      //   // contained an update for content_name_a.
14715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      //   EXPECT_EQ(old_content_desc_b, new_content_desc_b);
14725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      // }
14735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
14755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      initiator->ExpectSentStanza(
14765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org          IqAck("6", kInitiator, kResponder));
14775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(0U, initiator->sent_stanza_count());
14785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else {
14795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      responder->SkipUnsentStanza();
14805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
14815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->session->Terminate();
14835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
14845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("7", kInitiator, kResponder,
14855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              TerminateXml(resulting_protocol,
14865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                           cricket::STR_TERMINATE_SUCCESS)));
14875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->DeliverStanza(initiator->stanza());
14895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
14905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("7", kResponder, kInitiator));
14915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_SENTTERMINATE,
14925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
14935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE,
14945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              responder->session_state());
14955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
14965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
14975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Test an initiate with other content, called "main".
14985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestOtherContent(SignalingProtocol initiator_protocol,
14995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        SignalingProtocol responder_protocol,
15005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        SignalingProtocol resulting_protocol) {
15015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "main";
15025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "http://oink.splat/session";
15035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name_a = content_name;
15045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_a = "rtp";
15055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name_b = content_name;
15065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_b = "rtcp";
15075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string initiate_xml = InitiateXml(
15085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol,
15095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type);
15105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_a_xml = TransportInfo4Xml(
15115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol, content_name,
15125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 0, 1,
15135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 2, 3);
15145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_b_xml = "";
15155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_a_xml = TransportInfo4Xml(
15165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol, content_name,
15175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 4, 5,
15185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 6, 7);
15195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_b_xml = "";
15205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string accept_xml = AcceptXml(
15215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol,
15225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type);
15235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
15245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
15255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    TestSession(initiator_protocol, responder_protocol, resulting_protocol,
15265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_type,
15275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_type,
15285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_name_a, channel_name_a,
15295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_name_b, channel_name_b,
15305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                initiate_xml,
15315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                transport_info_a_xml, transport_info_b_xml,
15325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                transport_info_reply_a_xml, transport_info_reply_b_xml,
15335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                accept_xml);
15345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
15355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
15365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Test an initiate with audio content.
15375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestAudioContent(SignalingProtocol initiator_protocol,
15385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        SignalingProtocol responder_protocol,
15395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                        SignalingProtocol resulting_protocol) {
15405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string gingle_content_type = cricket::NS_GINGLE_AUDIO;
15415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = cricket::CN_AUDIO;
15425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = cricket::NS_JINGLE_RTP;
15435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_a = "rtp";
15445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_b = "rtcp";
15455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string initiate_xml = InitiateXml(
15465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol,
15475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        gingle_content_type,
15485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name, content_type,
15495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        "", "");
15505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_a_xml = TransportInfo4Xml(
15515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol, content_name,
15525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 0, 1,
15535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 2, 3);
15545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_b_xml = "";
15555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_a_xml = TransportInfo4Xml(
15565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol, content_name,
15575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 4, 5,
15585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 6, 7);
15595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_b_xml = "";
15605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string accept_xml = AcceptXml(
15615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol,
15625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        gingle_content_type,
15635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name, content_type,
15645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        "", "");
15655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
15665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
15675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    TestSession(initiator_protocol, responder_protocol, resulting_protocol,
15685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                gingle_content_type,
15695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_type,
15705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_name, channel_name_a,
15715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_name, channel_name_b,
15725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                initiate_xml,
15735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                transport_info_a_xml, transport_info_b_xml,
15745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                transport_info_reply_a_xml, transport_info_reply_b_xml,
15755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                accept_xml);
15765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
15775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
15785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Since media content is "split" into two contents (audio and
15795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // video), we need to treat it special.
15805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestVideoContents(SignalingProtocol initiator_protocol,
15815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                         SignalingProtocol responder_protocol,
15825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                         SignalingProtocol resulting_protocol) {
15835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = cricket::NS_JINGLE_RTP;
15845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string gingle_content_type = cricket::NS_GINGLE_VIDEO;
15855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name_a = cricket::CN_AUDIO;
15865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_a = "rtp";
15875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name_b = cricket::CN_VIDEO;
15885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_b = "video_rtp";
15895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
15905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string initiate_xml = InitiateXml(
15915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol,
15925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        gingle_content_type,
15935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type,
15945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_b, content_type);
15955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_a_xml = TransportInfo2Xml(
15965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol, content_name_a,
15975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 0, 1);
15985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_b_xml = TransportInfo2Xml(
15995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol, content_name_b,
16005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 2, 3);
16015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_a_xml = TransportInfo2Xml(
16025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol, content_name_a,
16035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 4, 5);
16045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_b_xml = TransportInfo2Xml(
16055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol, content_name_b,
16065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 6, 7);
16075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string accept_xml = AcceptXml(
16085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol,
16095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        gingle_content_type,
16105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type,
16115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_b, content_type);
16125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    TestSession(initiator_protocol, responder_protocol, resulting_protocol,
16145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                gingle_content_type,
16155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_type,
16165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_name_a, channel_name_a,
16175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_name_b, channel_name_b,
16185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                initiate_xml,
16195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                transport_info_a_xml, transport_info_b_xml,
16205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                transport_info_reply_a_xml, transport_info_reply_b_xml,
16215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                accept_xml);
16225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
16235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestBadRedirect(SignalingProtocol protocol) {
16255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "main";
16265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "http://oink.splat/session";
16275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_a = "chana";
16285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_b = "chanb";
16295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string initiate_xml = InitiateXml(
16305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        protocol, content_name, content_type);
16315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_xml = TransportInfo4Xml(
16325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        protocol, content_name,
16335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 0, 1,
16345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 2, 3);
16355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_xml = TransportInfo4Xml(
16365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        protocol, content_name,
16375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 4, 5,
16385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 6, 7);
16395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string accept_xml = AcceptXml(
16405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        protocol, content_name, content_type);
16415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string responder_full = kResponder + "/full";
16425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
16445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
16455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
16465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
16485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
16495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, protocol,
16505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
16515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, channel_name_a,
16525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, channel_name_b));
16535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> responder(
16555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
16565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       responder_full, protocol,
16575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
16585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  channel_name_a,
16595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  channel_name_b));
16605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Create Session and check channels and state.
16625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
16635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(1U, initiator->session_created_count);
16645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(kSessionId, initiator->session->id());
16655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->local_name(), kInitiator);
16665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_INIT,
16675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
16685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasChannel(content_name, 1));
16705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasChannel(content_name, 2));
16715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Initiate and expect initiate message sent.
16735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SessionDescription* offer = NewTestSessionDescription(
16745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name, content_type);
16755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
16765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->remote_name(), kResponder);
16775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->local_description(), offer);
16785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
16805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
16815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
16825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
16835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("0", kInitiator, kResponder, initiate_xml));
16845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Expect transport-info message from initiator.
16865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverAckToLastStanza();
16875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->PrepareCandidates();
16885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
16895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
16905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("1", kInitiator, kResponder, transport_info_xml));
16915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
16925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Send an unauthorized redirect to the initiator and expect it be ignored.
16935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->blow_up_on_error = false;
16945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const buzz::XmlElement* initiate_stanza = initiator->stanza();
16955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<buzz::XmlElement> redirect_stanza(
16965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        buzz::XmlElement::ForStr(
16975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org            IqError("ER", kResponder, kInitiator,
16985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    RedirectXml(protocol, initiate_xml, "not@allowed.com"))));
16995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->session_manager->OnFailedSend(
17005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiate_stanza, redirect_stanza.get());
17015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->remote_name(), kResponder);
17025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->blow_up_on_error = true;
17035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->error_count, 1);
17045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
17055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestGoodRedirect(SignalingProtocol protocol) {
17075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "main";
17085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "http://oink.splat/session";
17095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_a = "chana";
17105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_b = "chanb";
17115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string initiate_xml = InitiateXml(
17125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        protocol, content_name, content_type);
17135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_xml = TransportInfo4Xml(
17145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        protocol, content_name,
17155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 0, 1,
17165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 2, 3);
17175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_xml = TransportInfo4Xml(
17185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        protocol, content_name,
17195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 4, 5,
17205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 6, 7);
17215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string accept_xml = AcceptXml(
17225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        protocol, content_name, content_type);
17235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string responder_full = kResponder + "/full";
17245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
17265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
17275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
17285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
17305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
17315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, protocol,
17325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
17335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, channel_name_a,
17345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, channel_name_b));
17355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> responder(
17375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
17385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       responder_full, protocol,
17395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
17405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  channel_name_a,
17415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  channel_name_b));
17425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Create Session and check channels and state.
17445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
17455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(1U, initiator->session_created_count);
17465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(kSessionId, initiator->session->id());
17475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->local_name(), kInitiator);
17485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_INIT,
17495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
17505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasChannel(content_name, 1));
17525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasChannel(content_name, 2));
17535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Initiate and expect initiate message sent.
17555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SessionDescription* offer = NewTestSessionDescription(
17565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name, content_type);
17575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
17585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->remote_name(), kResponder);
17595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->local_description(), offer);
17605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
17625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
17635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
17645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
17655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("0", kInitiator, kResponder, initiate_xml));
17665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Expect transport-info message from initiator.
17685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverAckToLastStanza();
17695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->PrepareCandidates();
17705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
17715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
17725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("1", kInitiator, kResponder, transport_info_xml));
17735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Send a redirect to the initiator and expect all of the message
17755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // to be resent.
17765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    const buzz::XmlElement* initiate_stanza = initiator->stanza();
17775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<buzz::XmlElement> redirect_stanza(
17785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        buzz::XmlElement::ForStr(
17795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org            IqError("ER2", kResponder, kInitiator,
17805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    RedirectXml(protocol, initiate_xml, responder_full))));
17815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->session_manager->OnFailedSend(
17825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiate_stanza, redirect_stanza.get());
17835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(initiator->session->remote_name(), responder_full);
17845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
17865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
17875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("2", kInitiator, responder_full, initiate_xml));
17885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
17895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("3", kInitiator, responder_full, transport_info_xml));
17905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Deliver the initiate. Expect ack and session created with
17925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // transports.
17935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->DeliverStanza(
17945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("2", kInitiator, responder_full, initiate_xml));
17955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
17965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("2", responder_full, kInitiator));
17975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, responder->sent_stanza_count());
17985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
17995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(1U, responder->session_created_count);
18005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(kSessionId, responder->session->id());
18015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(responder->session->local_name(), responder_full);
18025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(responder->session->remote_name(), kInitiator);
18035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
18045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              responder->session_state());
18055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasChannel(content_name, 1));
18075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasChannel(content_name, 2));
18085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Deliver transport-info and expect ack.
18105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->DeliverStanza(
18115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("3", kInitiator, responder_full, transport_info_xml));
18125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
18135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("3", responder_full, kInitiator));
18145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Expect reply transport-infos sent to new remote JID
18165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->PrepareCandidates();
18175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
18185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
18195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("4", responder_full, kInitiator, transport_info_reply_xml));
18205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverStanza(responder->stanza());
18225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
18235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("4", kInitiator, responder_full));
18245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // The channels should be able to become writable at this point.  This
18265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // requires pinging, so it may take a little while.
18275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->chan_a->writable() &&
18285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     initiator->chan_a->readable(), kEventTimeout);
18295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->chan_b->writable() &&
18305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     initiator->chan_b->readable(), kEventTimeout);
18315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(responder->chan_a->writable() &&
18325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     responder->chan_a->readable(), kEventTimeout);
18335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(responder->chan_b->writable() &&
18345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     responder->chan_b->readable(), kEventTimeout);
18355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Accept the session and expect accept stanza.
18375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SessionDescription* answer = NewTestSessionDescription(
18385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name, content_type);
18395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->session->Accept(answer));
18405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(responder->session->local_description(), answer);
18415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
18435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("5", responder_full, kInitiator, accept_xml));
18445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, responder->sent_stanza_count());
18455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Deliver the accept message and expect an ack.
18475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverStanza(responder->stanza());
18485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
18495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
18505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("5", kInitiator, responder_full));
18515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, initiator->sent_stanza_count());
18525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Both sessions should be in progress and have functioning
18545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // channels.
18555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
18565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   initiator->session_state(), kEventTimeout);
18575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
18585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   responder->session_state(), kEventTimeout);
1859c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org    TestSendRecv(initiator->chan_a.get(), initiator->chan_b.get(),
1860c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org                 responder->chan_a.get(), responder->chan_b.get());
18615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
18625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestCandidatesInInitiateAndAccept(const std::string& test_name) {
18645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "main";
18655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "http://oink.splat/session";
18665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_a = "rtp";
18675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_b = "rtcp";
18685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SignalingProtocol protocol = PROTOCOL_JINGLE;
18695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
18715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
18725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
18735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
18755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
18765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, protocol,
18775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
18785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  channel_name_a,
18795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  channel_name_b));
18805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> responder(
18825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
18835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kResponder, protocol,
18845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
18855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  channel_name_a,
18865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  channel_name_b));
18875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Create Session and check channels and state.
18895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
18905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasTransport(content_name));
18915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasChannel(content_name, 1));
18925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasTransport(content_name));
18935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->HasChannel(content_name, 2));
18945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
18955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Initiate and expect initiate message sent.
18965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SessionDescription* offer = NewTestSessionDescription(
18975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name, content_type);
18985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
18995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
19015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
19025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
19035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
19045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("0", kInitiator, kResponder,
19055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              InitiateXml(protocol, content_name, content_type)));
19065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Fake the delivery the initiate and candidates together.
19085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->DeliverStanza(
19095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("A", kInitiator, kResponder,
19105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org            JingleInitiateActionXml(
19115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                JingleContentXml(
19125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    content_name, content_type, kTransportType,
19135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    P2pCandidateXml(channel_name_a, 0) +
19145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    P2pCandidateXml(channel_name_a, 1) +
19155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    P2pCandidateXml(channel_name_b, 2) +
19165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    P2pCandidateXml(channel_name_b, 3)))));
19175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
19185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("A", kResponder, kInitiator));
19195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, responder->sent_stanza_count());
19205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(1U, responder->session_created_count);
19225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(kSessionId, responder->session->id());
19235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(responder->session->local_name(), kResponder);
19245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(responder->session->remote_name(), kInitiator);
19255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
19265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              responder->session_state());
19275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasTransport(content_name));
19295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasChannel(content_name, 1));
19305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasTransport(content_name));
19315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->HasChannel(content_name, 2));
19325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Expect transport-info message from initiator.
19345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // But don't send candidates until initiate ack is received.
19355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverAckToLastStanza();
19365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->PrepareCandidates();
19375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
19385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
19395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("1", kInitiator, kResponder,
19405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              TransportInfo4Xml(protocol, content_name,
19415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                channel_name_a, 0, 1,
19425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                channel_name_b, 2, 3)));
19435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->PrepareCandidates();
19455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(responder->sent_stanza_count() > 0, kEventTimeout);
19465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
19475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("2", kResponder, kInitiator,
19485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              TransportInfo4Xml(protocol, content_name,
19495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                channel_name_a, 4, 5,
19505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                                channel_name_b, 6, 7)));
19515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Accept the session and expect accept stanza.
19535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SessionDescription* answer = NewTestSessionDescription(
19545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name, content_type);
19555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(responder->session->Accept(answer));
19565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
19585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("3", kResponder, kInitiator,
19595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              AcceptXml(protocol, content_name, content_type)));
19605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, responder->sent_stanza_count());
19615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Fake the delivery the accept and candidates together.
19635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverStanza(
19645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("B", kResponder, kInitiator,
19655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org            JingleActionXml("session-accept",
19665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                JingleContentXml(
19675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    content_name, content_type, kTransportType,
19685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    P2pCandidateXml(channel_name_a, 4) +
19695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    P2pCandidateXml(channel_name_a, 5) +
19705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    P2pCandidateXml(channel_name_b, 6) +
19715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                    P2pCandidateXml(channel_name_b, 7)))));
19725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->sent_stanza_count() > 0, kEventTimeout);
19735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
19745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("B", kInitiator, kResponder));
19755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(0U, initiator->sent_stanza_count());
19765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // The channels should be able to become writable at this point.  This
19785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // requires pinging, so it may take a little while.
19795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->chan_a->writable() &&
19805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     initiator->chan_a->readable(), kEventTimeout);
19815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(initiator->chan_b->writable() &&
19825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     initiator->chan_b->readable(), kEventTimeout);
19835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(responder->chan_a->writable() &&
19845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     responder->chan_a->readable(), kEventTimeout);
19855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE_WAIT(responder->chan_b->writable() &&
19865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                     responder->chan_b->readable(), kEventTimeout);
19875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
19895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Both sessions should be in progress and have functioning
19905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // channels.
19915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(protocol, initiator->session->current_protocol());
19925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(protocol, responder->session->current_protocol());
19935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
19945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   initiator->session_state(), kEventTimeout);
19955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ_WAIT(cricket::BaseSession::STATE_INPROGRESS,
19965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                   responder->session_state(), kEventTimeout);
1997c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org    TestSendRecv(initiator->chan_a.get(), initiator->chan_b.get(),
1998c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org                 responder->chan_a.get(), responder->chan_b.get());
19995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
20005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Tests that when an initiator terminates right after initiate,
20025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // everything behaves correctly.
20035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestEarlyTerminationFromInitiator(SignalingProtocol protocol) {
20045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "main";
20055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "http://oink.splat/session";
20065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
20085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
20095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
20105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
20125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
20135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, protocol,
20145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
20155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, "a",
20165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, "b"));
20175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> responder(
20195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
20205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kResponder, protocol,
20215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
20225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  "a",
20235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name,  "b"));
20245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Send initiate
20265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
20275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->session->Initiate(
20285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        kResponder, NewTestSessionDescription(content_name, content_type)));
20295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
20305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("0", kInitiator, kResponder,
20315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              InitiateXml(protocol, content_name, content_type)));
20325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
20335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
20345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->DeliverStanza(initiator->stanza());
20365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
20375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("0", kResponder, kInitiator));
20385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDINITIATE,
20395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              responder->session_state());
20405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->session->TerminateWithReason(cricket::STR_TERMINATE_ERROR);
20425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
20435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("1", kInitiator, kResponder,
20445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              TerminateXml(protocol, cricket::STR_TERMINATE_ERROR)));
20455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_SENTTERMINATE,
20465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
20475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->DeliverStanza(initiator->stanza());
20495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    responder->ExpectSentStanza(
20505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("1", kResponder, kInitiator));
20515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE,
20525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              responder->session_state());
20535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
20545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // Tests that when the responder rejects, everything behaves
20565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  // correctly.
20575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestRejection(SignalingProtocol protocol) {
20585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "main";
20595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "http://oink.splat/session";
20605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
20625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
20635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
20645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
20665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
20675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, protocol,
20685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
20695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, "a",
20705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, "b"));
20715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Send initiate
20735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
20745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->session->Initiate(
20755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        kResponder, NewTestSessionDescription(content_name, content_type)));
20765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
20775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("0", kInitiator, kResponder,
20785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              InitiateXml(protocol, content_name, content_type)));
20795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(cricket::BaseSession::STATE_SENTINITIATE,
20805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              initiator->session_state());
20815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->DeliverStanza(
20835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("1", kResponder, kInitiator,
20845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org              RejectXml(protocol, cricket::STR_TERMINATE_ERROR)));
20855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
20865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqAck("1", kInitiator, kResponder));
20875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    if (protocol == PROTOCOL_JINGLE) {
20885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDTERMINATE,
20895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                initiator->session_state());
20905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    } else {
20915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      EXPECT_EQ(cricket::BaseSession::STATE_RECEIVEDREJECT,
20925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                initiator->session_state());
20935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    }
20945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
20955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
20965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestTransportMux() {
20975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalingProtocol initiator_protocol = PROTOCOL_JINGLE;
20985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalingProtocol responder_protocol = PROTOCOL_JINGLE;
20995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    SignalingProtocol resulting_protocol = PROTOCOL_JINGLE;
21005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = cricket::NS_JINGLE_RTP;
21015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string gingle_content_type = cricket::NS_GINGLE_VIDEO;
21025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name_a = cricket::CN_AUDIO;
21035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_a = "rtp";
21045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name_b = cricket::CN_VIDEO;
21055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string channel_name_b = "video_rtp";
21065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string initiate_xml = InitiateXml(
21085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol,
21095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        gingle_content_type,
21105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type,
21115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_b, content_type, true);
21125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_a_xml = TransportInfo2Xml(
21135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol, content_name_a,
21145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 0, 1);
21155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_b_xml = TransportInfo2Xml(
21165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator_protocol, content_name_b,
21175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 2, 3);
21185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_a_xml = TransportInfo2Xml(
21195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol, content_name_a,
21205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_a, 4, 5);
21215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string transport_info_reply_b_xml = TransportInfo2Xml(
21225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol, content_name_b,
21235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        channel_name_b, 6, 7);
21245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string accept_xml = AcceptXml(
21255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        resulting_protocol,
21265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        gingle_content_type,
21275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_a, content_type,
21285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name_b, content_type, true);
21295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    TestSession(initiator_protocol, responder_protocol, resulting_protocol,
21315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                gingle_content_type,
21325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_type,
21335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_name_a, channel_name_a,
21345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                content_name_b, channel_name_b,
21355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                initiate_xml,
21365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                transport_info_a_xml, transport_info_b_xml,
21375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                transport_info_reply_a_xml, transport_info_reply_b_xml,
21385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                accept_xml,
21395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                true);
21405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
21415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestSendDescriptionInfo() {
21435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
21445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
21455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
21465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "content-name";
21485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "content-type";
21495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
21505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
21515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, PROTOCOL_JINGLE,
21525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
21535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, "",
21545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       "",  ""));
21555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
21575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SessionDescription* offer = NewTestSessionDescription(
21585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name, content_type);
21595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string initiate_xml = InitiateXml(
21605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        PROTOCOL_JINGLE, content_name, content_type);
21615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::ContentInfos contents;
21635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    TestContentDescription content(content_type, content_type);
21645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    contents.push_back(
21655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::ContentInfo(content_name, content_type, &content));
21665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string description_info_xml = JingleDescriptionInfoXml(
21675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        content_name, content_type);
21685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->session->Initiate(kResponder, offer));
21705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
21715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("0", kInitiator, kResponder, initiate_xml));
21725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->session->SendDescriptionInfoMessage(contents));
21745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->ExpectSentStanza(
21755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        IqSet("1", kInitiator, kResponder, description_info_xml));
21765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
21775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void DoTestSignalNewDescription(
21795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      TestClient* client,
21805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::BaseSession::State state,
21815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::ContentAction expected_content_action,
21825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org      cricket::ContentSource expected_content_source) {
21835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // Clean up before the new test.
21845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    client->new_local_description = false;
21855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    client->new_remote_description = false;
21865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    client->SetSessionState(state);
21885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ((expected_content_source == cricket::CS_LOCAL),
21895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               client->new_local_description);
21905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ((expected_content_source == cricket::CS_REMOTE),
21915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org               client->new_remote_description);
21925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(expected_content_action, client->last_content_action);
21935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(expected_content_source, client->last_content_source);
21945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
21955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
21965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestCallerSignalNewDescription() {
21975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
21985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
21995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
22005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "content-name";
22025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "content-type";
22035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
22045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
22055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, PROTOCOL_JINGLE,
22065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
22075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, "",
22085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       "",  ""));
22095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
22115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // send offer -> send update offer ->
22135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // receive pr answer -> receive update pr answer ->
22145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // receive answer
22155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_SENTINITIATE,
22175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_OFFER, cricket::CS_LOCAL);
22185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_SENTINITIATE,
22215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_OFFER, cricket::CS_LOCAL);
22225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_RECEIVEDPRACCEPT,
22255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_PRANSWER, cricket::CS_REMOTE);
22265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_RECEIVEDPRACCEPT,
22295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_PRANSWER, cricket::CS_REMOTE);
22305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_RECEIVEDACCEPT,
22335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_ANSWER, cricket::CS_REMOTE);
22345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
22355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestCalleeSignalNewDescription() {
22375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
22385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
22395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
22405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "content-name";
22425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "content-type";
22435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
22445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
22455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, PROTOCOL_JINGLE,
22465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
22475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, "",
22485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       "",  ""));
22495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
22515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // receive offer -> receive update offer ->
22535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // send pr answer -> send update pr answer ->
22545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // send answer
22555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_RECEIVEDINITIATE,
22575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_OFFER, cricket::CS_REMOTE);
22585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_RECEIVEDINITIATE,
22615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_OFFER, cricket::CS_REMOTE);
22625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_SENTPRACCEPT,
22655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_PRANSWER, cricket::CS_LOCAL);
22665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_SENTPRACCEPT,
22695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_PRANSWER, cricket::CS_LOCAL);
22705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    DoTestSignalNewDescription(
22725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        initiator.get(), cricket::BaseSession::STATE_SENTACCEPT,
22735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        cricket::CA_ANSWER, cricket::CS_LOCAL);
22745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
22755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  void TestGetTransportStats() {
22775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<cricket::PortAllocator> allocator(
22785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestPortAllocator());
22795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    int next_message_id = 0;
22805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_name = "content-name";
22825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    std::string content_type = "content-type";
22835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    talk_base::scoped_ptr<TestClient> initiator(
22845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org        new TestClient(allocator.get(), &next_message_id,
22855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       kInitiator, PROTOCOL_JINGLE,
22865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_type,
22875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       content_name, "",
22885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org                       "",  ""));
22895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    initiator->CreateSession();
22905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    cricket::SessionStats stats;
22925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_TRUE(initiator->session->GetStats(&stats));
22935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    // At initiation, there are 2 transports.
22945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(2ul, stats.proxy_to_transport.size());
22955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org    EXPECT_EQ(2ul, stats.transport_stats.size());
22965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  }
22975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org};
22985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
22995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// For each of these, "X => Y = Z" means "if a client with protocol X
23005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// initiates to a client with protocol Y, they end up speaking protocol Z.
23015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Gingle => Gingle = Gingle (with other content)
23035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleToGingleOtherContent) {
23045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestOtherContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
23055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Gingle => Gingle = Gingle (with audio content)
23085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleToGingleAudioContent) {
23095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestAudioContent(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
23105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Gingle => Gingle = Gingle (with video contents)
23135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleToGingleVideoContents) {
23145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestVideoContents(PROTOCOL_GINGLE, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
23155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Jingle => Jingle = Jingle (with other content)
23185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleToJingleOtherContent) {
23195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestOtherContent(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
23205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Jingle => Jingle = Jingle (with audio content)
23235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleToJingleAudioContent) {
23245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestAudioContent(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
23255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Jingle => Jingle = Jingle (with video contents)
23285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleToJingleVideoContents) {
23295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestVideoContents(PROTOCOL_JINGLE, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
23305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hybrid => Hybrid = Jingle (with other content)
23335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridToHybridOtherContent) {
23345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
23355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hybrid => Hybrid = Jingle (with audio content)
23385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridToHybridAudioContent) {
23395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
23405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hybrid => Hybrid = Jingle (with video contents)
23435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridToHybridVideoContents) {
23445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
23455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Gingle => Hybrid = Gingle (with other content)
23485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleToHybridOtherContent) {
23495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestOtherContent(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE);
23505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Gingle => Hybrid = Gingle (with audio content)
23535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleToHybridAudioContent) {
23545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestAudioContent(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE);
23555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Gingle => Hybrid = Gingle (with video contents)
23585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleToHybridVideoContents) {
23595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestVideoContents(PROTOCOL_GINGLE, PROTOCOL_HYBRID, PROTOCOL_GINGLE);
23605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Jingle => Hybrid = Jingle (with other content)
23635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleToHybridOtherContent) {
23645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestOtherContent(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
23655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Jingle => Hybrid = Jingle (with audio content)
23685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleToHybridAudioContent) {
23695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestAudioContent(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
23705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Jingle => Hybrid = Jingle (with video contents)
23735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleToHybridVideoContents) {
23745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestVideoContents(PROTOCOL_JINGLE, PROTOCOL_HYBRID, PROTOCOL_JINGLE);
23755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hybrid => Gingle = Gingle (with other content)
23785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridToGingleOtherContent) {
23795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
23805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hybrid => Gingle = Gingle (with audio content)
23835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridToGingleAudioContent) {
23845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
23855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hybrid => Gingle = Gingle (with video contents)
23885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridToGingleVideoContents) {
23895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_GINGLE, PROTOCOL_GINGLE);
23905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hybrid => Jingle = Jingle (with other content)
23935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridToJingleOtherContent) {
23945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestOtherContent(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
23955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
23965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
23975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hybrid => Jingle = Jingle (with audio content)
23985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridToJingleAudioContent) {
23995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestAudioContent(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
24005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Hybrid => Jingle = Jingle (with video contents)
24035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridToJingleVideoContents) {
24045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestVideoContents(PROTOCOL_HYBRID, PROTOCOL_JINGLE, PROTOCOL_JINGLE);
24055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleEarlyTerminationFromInitiator) {
24085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestEarlyTerminationFromInitiator(PROTOCOL_GINGLE);
24095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleEarlyTerminationFromInitiator) {
24125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestEarlyTerminationFromInitiator(PROTOCOL_JINGLE);
24135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, HybridEarlyTerminationFromInitiator) {
24165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestEarlyTerminationFromInitiator(PROTOCOL_HYBRID);
24175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleRejection) {
24205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestRejection(PROTOCOL_GINGLE);
24215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleRejection) {
24245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestRejection(PROTOCOL_JINGLE);
24255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleGoodRedirect) {
24285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestGoodRedirect(PROTOCOL_GINGLE);
24295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleGoodRedirect) {
24325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestGoodRedirect(PROTOCOL_JINGLE);
24335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, GingleBadRedirect) {
24365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestBadRedirect(PROTOCOL_GINGLE);
24375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, JingleBadRedirect) {
24405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestBadRedirect(PROTOCOL_JINGLE);
24415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, TestCandidatesInInitiateAndAccept) {
24445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestCandidatesInInitiateAndAccept("Candidates in initiate/accept");
24455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, TestTransportMux) {
24485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestTransportMux();
24495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, TestSendDescriptionInfo) {
24525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestSendDescriptionInfo();
24535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, TestCallerSignalNewDescription) {
24565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestCallerSignalNewDescription();
24575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, TestCalleeSignalNewDescription) {
24605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestCalleeSignalNewDescription();
24615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
24625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org
24635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgTEST_F(SessionTest, TestGetTransportStats) {
24645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org  TestGetTransportStats();
24655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}
2466