10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2012, Google Inc.
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer.
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     and/or other materials provided with the distribution.
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     derived from this software without specific prior written permission.
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/app/webrtc/webrtcsession.h"
290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
30b9518277716cf5081d3058d86ab7d98b78f696e8pbos@webrtc.org#include <limits.h>
31b9518277716cf5081d3058d86ab7d98b78f696e8pbos@webrtc.org
320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <algorithm>
330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <vector>
340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/app/webrtc/jsepicecandidate.h"
360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/app/webrtc/jsepsessiondescription.h"
370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/app/webrtc/mediaconstraintsinterface.h"
380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/app/webrtc/mediastreamsignaling.h"
390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/app/webrtc/peerconnectioninterface.h"
405aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h"
410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/media/base/constants.h"
420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/media/base/videocapturer.h"
430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/session/media/channel.h"
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/session/media/channelmanager.h"
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/session/media/mediasession.h"
46cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/basictypes.h"
47cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/helpers.h"
48cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/logging.h"
49cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/stringencode.h"
50cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/stringutils.h"
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::ContentInfo;
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::ContentInfos;
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::MediaContentDescription;
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::SessionDescription;
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgusing cricket::TransportInfo;
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace webrtc {
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Error messages
617162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgconst char kBundleWithoutRtcpMux[] = "RTCP-MUX must be enabled when BUNDLE "
627162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org                                     "is enabled.";
63f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgconst char kCreateChannelFailed[] = "Failed to create channels.";
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char kInvalidCandidates[] = "Description contains invalid candidates.";
650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char kInvalidSdp[] = "Invalid session description.";
660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char kMlineMismatch[] =
67f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    "Offer and answer descriptions m-lines are not matching. Rejecting answer.";
68f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgconst char kPushDownTDFailed[] =
69f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    "Failed to push down transport description:";
70ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.orgconst char kSdpWithoutDtlsFingerprint[] =
71ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    "Called with SDP without DTLS fingerprint.";
72ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.orgconst char kSdpWithoutSdesCrypto[] =
73ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    "Called with SDP without SDES crypto.";
748841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.orgconst char kSdpWithoutIceUfragPwd[] =
75ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    "Called with SDP without ice-ufrag and ice-pwd.";
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgconst char kSessionError[] = "Session error code: ";
77f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgconst char kSessionErrorDesc[] = "Session error description: ";
78b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.orgconst int kMaxUnsignalledRecvStreams = 20;
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Compares |answer| against |offer|. Comparision is done
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// for number of m-lines in answer against offer. If matches true will be
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// returned otherwise false.
830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic bool VerifyMediaDescriptions(
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const SessionDescription* answer, const SessionDescription* offer) {
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (offer->contents().size() != answer->contents().size())
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (size_t i = 0; i < offer->contents().size(); ++i) {
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if ((offer->contents()[i].name) != answer->contents()[i].name) {
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
92cf402e4e30f3b7538d0d71f5fc91b505e496247dwu@webrtc.org    const MediaContentDescription* offer_mdesc =
93cf402e4e30f3b7538d0d71f5fc91b505e496247dwu@webrtc.org        static_cast<const MediaContentDescription*>(
94cf402e4e30f3b7538d0d71f5fc91b505e496247dwu@webrtc.org            offer->contents()[i].description);
95cf402e4e30f3b7538d0d71f5fc91b505e496247dwu@webrtc.org    const MediaContentDescription* answer_mdesc =
96cf402e4e30f3b7538d0d71f5fc91b505e496247dwu@webrtc.org        static_cast<const MediaContentDescription*>(
97cf402e4e30f3b7538d0d71f5fc91b505e496247dwu@webrtc.org            answer->contents()[i].description);
98cf402e4e30f3b7538d0d71f5fc91b505e496247dwu@webrtc.org    if (offer_mdesc->type() != answer_mdesc->type()) {
99cf402e4e30f3b7538d0d71f5fc91b505e496247dwu@webrtc.org      return false;
100cf402e4e30f3b7538d0d71f5fc91b505e496247dwu@webrtc.org    }
1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Checks that each non-rejected content has SDES crypto keys or a DTLS
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// fingerprint. Mismatches, such as replying with a DTLS fingerprint to SDES
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// keys, will be caught in Transport negotiation, and backstopped by Channel's
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// |secure_required| check.
1095528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.orgstatic bool VerifyCrypto(const SessionDescription* desc,
1105528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org                         bool dtls_enabled,
1115528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org                         std::string* error) {
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const ContentInfos& contents = desc->contents();
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (size_t index = 0; index < contents.size(); ++index) {
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const ContentInfo* cinfo = &contents[index];
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (cinfo->rejected) {
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      continue;
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // If the content isn't rejected, crypto must be present.
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const MediaContentDescription* media =
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        static_cast<const MediaContentDescription*>(cinfo->description);
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const TransportInfo* tinfo = desc->GetTransportInfoByName(cinfo->name);
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!media || !tinfo) {
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Something is not right.
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_ERROR) << kInvalidSdp;
1265528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      *error = kInvalidSdp;
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
129ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    if (dtls_enabled) {
1305528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      if (!tinfo->description.identity_fingerprint) {
131ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org        LOG(LS_WARNING) <<
132ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org            "Session description must have DTLS fingerprint if DTLS enabled.";
133ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org        *error = kSdpWithoutDtlsFingerprint;
1345528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org        return false;
1355528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      }
136ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    } else {
137ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org      if (media->cryptos().empty()) {
1385528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org        LOG(LS_WARNING) <<
1395528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org            "Session description must have SDES when DTLS disabled.";
140ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org        *error = kSdpWithoutSdesCrypto;
1415528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org        return false;
1425528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      }
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1498841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org// Checks that each non-rejected content has ice-ufrag and ice-pwd set.
1508841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.orgstatic bool VerifyIceUfragPwdPresent(const SessionDescription* desc) {
1518841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org  const ContentInfos& contents = desc->contents();
1528841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org  for (size_t index = 0; index < contents.size(); ++index) {
1538841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    const ContentInfo* cinfo = &contents[index];
1548841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    if (cinfo->rejected) {
1558841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org      continue;
1568841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    }
1578841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org
1588841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    // If the content isn't rejected, ice-ufrag and ice-pwd must be present.
1598841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    const TransportInfo* tinfo = desc->GetTransportInfoByName(cinfo->name);
1608841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    if (!tinfo) {
1618841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org      // Something is not right.
1628841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org      LOG(LS_ERROR) << kInvalidSdp;
1638841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org      return false;
1648841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    }
1658841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    if (tinfo->description.ice_ufrag.empty() ||
1668841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org        tinfo->description.ice_pwd.empty()) {
1678841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org      LOG(LS_ERROR) << "Session description must have ice ufrag and pwd.";
1688841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org      return false;
1698841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org    }
1708841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org  }
1718841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org  return true;
1728841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org}
1738841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org
1745aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org// Forces |sdesc->crypto_required| to the appropriate state based on the
1755aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org// current security policy, to ensure a failure occurs if there is an error
1765aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org// in crypto negotiation.
1775aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org// Called when processing the local session description.
178ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.orgstatic void UpdateSessionDescriptionSecurePolicy(cricket::CryptoType type,
179ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org                                                 SessionDescription* sdesc) {
1805aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  if (!sdesc) {
1815aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    return;
1825aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  }
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1845aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  // Updating the |crypto_required_| in MediaContentDescription to the
1855aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  // appropriate state based on the current security policy.
1865aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  for (cricket::ContentInfos::iterator iter = sdesc->contents().begin();
1875aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org       iter != sdesc->contents().end(); ++iter) {
1885aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    if (cricket::IsMediaContent(&*iter)) {
1895aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      MediaContentDescription* mdesc =
1905aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org          static_cast<MediaContentDescription*> (iter->description);
1915aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      if (mdesc) {
192ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org        mdesc->set_crypto_required(type);
1935aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      }
1945aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    }
1955aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  }
1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic bool GetAudioSsrcByTrackId(
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const SessionDescription* session_description,
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string& track_id, uint32 *ssrc) {
2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::ContentInfo* audio_info =
2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      cricket::GetFirstAudioContent(session_description);
2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!audio_info) {
2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Audio not used in this call";
2050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
2060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::MediaContentDescription* audio_content =
2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      static_cast<const cricket::MediaContentDescription*>(
2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          audio_info->description);
2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::StreamParams stream;
2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!cricket::GetStreamByIds(audio_content->streams(), "", track_id,
2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               &stream)) {
2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
2150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  *ssrc = stream.first_ssrc();
2170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic bool GetTrackIdBySsrc(const SessionDescription* session_description,
2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             uint32 ssrc, std::string* track_id) {
2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(track_id != NULL);
2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::StreamParams stream_out;
2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::ContentInfo* audio_info =
2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      cricket::GetFirstAudioContent(session_description);
227662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org  if (audio_info) {
228662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org    const cricket::MediaContentDescription* audio_content =
229662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org        static_cast<const cricket::MediaContentDescription*>(
230662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org            audio_info->description);
231662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org
232662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org    if (cricket::GetStreamBySsrc(audio_content->streams(), ssrc, &stream_out)) {
233662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org      *track_id = stream_out.id;
234662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org      return true;
235662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org    }
2360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::ContentInfo* video_info =
2390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      cricket::GetFirstVideoContent(session_description);
240662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org  if (video_info) {
241662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org    const cricket::MediaContentDescription* video_content =
242662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org        static_cast<const cricket::MediaContentDescription*>(
243662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org            video_info->description);
244662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org
245662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org    if (cricket::GetStreamBySsrc(video_content->streams(), ssrc, &stream_out)) {
246662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org      *track_id = stream_out.id;
247662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org      return true;
248662c7aa5d714ca021559d4e7e9de5b1ffdcf9b19jiayl@webrtc.org    }
2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return false;
2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
253f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic bool BadSdp(const std::string& source,
254f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                   const std::string& type,
255f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                   const std::string& reason,
256f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                   std::string* err_desc) {
257f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  std::ostringstream desc;
258f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  desc << "Failed to set " << source << " " << type << " sdp: " << reason;
259f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org
2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (err_desc) {
261f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    *err_desc = desc.str();
2620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
263f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  LOG(LS_ERROR) << desc.str();
2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return false;
2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic bool BadSdp(cricket::ContentSource source,
268f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                   const std::string& type,
269f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                   const std::string& reason,
270f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                   std::string* err_desc) {
2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (source == cricket::CS_LOCAL) {
272f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadSdp("local", type, reason, err_desc);
2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
274f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadSdp("remote", type, reason, err_desc);
2750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
278f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic bool BadLocalSdp(const std::string& type,
279f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                        const std::string& reason,
280f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                        std::string* err_desc) {
281f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  return BadSdp(cricket::CS_LOCAL, type, reason, err_desc);
282f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org}
283f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org
284f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic bool BadRemoteSdp(const std::string& type,
285f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                         const std::string& reason,
286f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                         std::string* err_desc) {
287f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  return BadSdp(cricket::CS_REMOTE, type, reason, err_desc);
288f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org}
289f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org
290f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic bool BadOfferSdp(cricket::ContentSource source,
291f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                        const std::string& reason,
292f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                        std::string* err_desc) {
293f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  return BadSdp(source, SessionDescriptionInterface::kOffer, reason, err_desc);
294f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org}
295f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org
296f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic bool BadPranswerSdp(cricket::ContentSource source,
297f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                           const std::string& reason,
298f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                           std::string* err_desc) {
299f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  return BadSdp(source, SessionDescriptionInterface::kPrAnswer,
300f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                reason, err_desc);
301f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org}
302f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org
303f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic bool BadAnswerSdp(cricket::ContentSource source,
304f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                         const std::string& reason,
305f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                         std::string* err_desc) {
306f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  return BadSdp(source, SessionDescriptionInterface::kAnswer, reason, err_desc);
3070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#define GET_STRING_OF_STATE(state)  \
3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  case cricket::BaseSession::state:  \
3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    result = #state;  \
3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    break;
3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic std::string GetStateString(cricket::BaseSession::State state) {
3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string result;
3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (state) {
3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_INIT)
3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_SENTINITIATE)
3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_RECEIVEDINITIATE)
3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_SENTPRACCEPT)
3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_SENTACCEPT)
3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_RECEIVEDPRACCEPT)
3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_RECEIVEDACCEPT)
3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_SENTMODIFY)
3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_RECEIVEDMODIFY)
3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_SENTREJECT)
3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_RECEIVEDREJECT)
3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_SENTREDIRECT)
3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_SENTTERMINATE)
3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_RECEIVEDTERMINATE)
3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_INPROGRESS)
3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GET_STRING_OF_STATE(STATE_DEINIT)
3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(false);
3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return result;
3380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
340f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org#define GET_STRING_OF_ERROR_CODE(err)  \
3410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  case cricket::BaseSession::err:  \
3420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    result = #err;  \
3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    break;
3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
345f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic std::string GetErrorCodeString(cricket::BaseSession::Error err) {
3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string result;
3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (err) {
348f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    GET_STRING_OF_ERROR_CODE(ERROR_NONE)
349f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    GET_STRING_OF_ERROR_CODE(ERROR_TIME)
350f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    GET_STRING_OF_ERROR_CODE(ERROR_RESPONSE)
351f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    GET_STRING_OF_ERROR_CODE(ERROR_NETWORK)
352f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    GET_STRING_OF_ERROR_CODE(ERROR_CONTENT)
353f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    GET_STRING_OF_ERROR_CODE(ERROR_TRANSPORT)
3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(false);
3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return result;
3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
361f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic std::string MakeErrorString(const std::string& error,
362f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                                   const std::string& desc) {
363f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  std::ostringstream ret;
364f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  ret << error << " " << desc;
365f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  return ret.str();
366f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org}
367f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org
368f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstatic std::string MakeTdErrorString(const std::string& desc) {
369f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  return MakeErrorString(kPushDownTDFailed, desc);
3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3723865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org// Set |option| to the highest-priority value of |key| in the optional
3733865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org// constraints if the key is found and has a valid value.
374d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.orgtemplate<typename T>
3753865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.orgstatic void SetOptionFromOptionalConstraint(
3763865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org    const MediaConstraintsInterface* constraints,
377d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org    const std::string& key, cricket::Settable<T>* option) {
3783865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org  if (!constraints) {
3793865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org    return;
3803865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org  }
3813865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org  std::string string_value;
382d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org  T value;
3833865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org  if (constraints->GetOptional().FindFirst(key, &string_value)) {
3842a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    if (rtc::FromString(string_value, &value)) {
3853865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org      option->Set(value);
3863865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org    }
3873865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org  }
3883865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org}
3893865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org
3902ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.orguint32 ConvertIceTransportTypeToCandidateFilter(
3912ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org    PeerConnectionInterface::IceTransportsType type) {
3922ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org  switch (type) {
3932ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org    case PeerConnectionInterface::kNone:
3942ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org        return cricket::CF_NONE;
3952ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org    case PeerConnectionInterface::kRelay:
3962ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org        return cricket::CF_RELAY;
3972ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org    case PeerConnectionInterface::kNoHost:
3982ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org        return (cricket::CF_ALL & ~cricket::CF_HOST);
3992ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org    case PeerConnectionInterface::kAll:
4002ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org        return cricket::CF_ALL;
4012ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org    default: ASSERT(false);
4022ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org  }
4032ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org  return cricket::CF_NONE;
4042ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org}
4052ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org
4060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Help class used to remember if a a remote peer has requested ice restart by
4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// by sending a description with new ice ufrag and password.
4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgclass IceRestartAnswerLatch {
4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org public:
4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  IceRestartAnswerLatch() : ice_restart_(false) { }
4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4125aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  // Returns true if CheckForRemoteIceRestart has been called with a new session
4135aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  // description where ice password and ufrag has changed since last time
4145aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  // Reset() was called.
4155aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  bool Get() const {
4165aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    return ice_restart_;
4175aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  }
4185aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
4195aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  void Reset() {
4200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (ice_restart_) {
4210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ice_restart_ = false;
4220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  void CheckForRemoteIceRestart(
4260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      const SessionDescriptionInterface* old_desc,
4270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      const SessionDescriptionInterface* new_desc) {
4280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!old_desc || new_desc->type() != SessionDescriptionInterface::kOffer) {
4290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return;
4300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const SessionDescription* new_sd = new_desc->description();
4320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const SessionDescription* old_sd = old_desc->description();
4330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const ContentInfos& contents = new_sd->contents();
4340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (size_t index = 0; index < contents.size(); ++index) {
4350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      const ContentInfo* cinfo = &contents[index];
4360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (cinfo->rejected) {
4370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        continue;
4380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
4390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // If the content isn't rejected, check if ufrag and password has
4400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // changed.
4410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      const cricket::TransportDescription* new_transport_desc =
4420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          new_sd->GetTransportDescriptionByName(cinfo->name);
4430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      const cricket::TransportDescription* old_transport_desc =
4440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          old_sd->GetTransportDescriptionByName(cinfo->name);
4450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!new_transport_desc || !old_transport_desc) {
4460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        // No transport description exist. This is not an ice restart.
4470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        continue;
4480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
44939c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org      if (cricket::IceCredentialsChanged(old_transport_desc->ice_ufrag,
45039c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org                                         old_transport_desc->ice_pwd,
45139c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org                                         new_transport_desc->ice_ufrag,
45239c443b6209621f0e8537e14514cc4c8b1dd5fadjiayl@webrtc.org                                         new_transport_desc->ice_pwd)) {
4530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LOG(LS_INFO) << "Remote peer request ice restart.";
4540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ice_restart_ = true;
4550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        break;
4560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
4570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org private:
4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool ice_restart_;
4620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org};
4630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4645aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgWebRtcSession::WebRtcSession(
4655aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    cricket::ChannelManager* channel_manager,
4662a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::Thread* signaling_thread,
4672a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::Thread* worker_thread,
4685aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    cricket::PortAllocator* port_allocator,
4695aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    MediaStreamSignaling* mediastream_signaling)
4700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    : cricket::BaseSession(signaling_thread, worker_thread, port_allocator,
4712a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                           rtc::ToString(rtc::CreateRandomId64() &
4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                               LLONG_MAX),
4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           cricket::NS_JINGLE_RTP, false),
4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // RFC 3264: The numeric value of the session id and version in the
4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // o line MUST be representable with a "64 bit signed integer".
4760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Due to this constraint session id |sid_| is max limited to LLONG_MAX.
4770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      channel_manager_(channel_manager),
4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      mediastream_signaling_(mediastream_signaling),
4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ice_observer_(NULL),
4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ice_connection_state_(PeerConnectionInterface::kIceConnectionNew),
4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      older_version_remote_peer_(false),
4825528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      dtls_enabled_(false),
4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      data_channel_type_(cricket::DCT_NONE),
4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ice_restart_latch_(new IceRestartAnswerLatch) {
4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgWebRtcSession::~WebRtcSession() {
4885462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  // Destroy video_channel_ first since it may have a pointer to the
4895462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  // voice_channel_.
4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (video_channel_.get()) {
4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalVideoChannelDestroyed();
4920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    channel_manager_->DestroyVideoChannel(video_channel_.release());
4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4945462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  if (voice_channel_.get()) {
4955462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org    SignalVoiceChannelDestroyed();
4965462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org    channel_manager_->DestroyVoiceChannel(voice_channel_.release());
4975462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  }
4980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (data_channel_.get()) {
4990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalDataChannelDestroyed();
5000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    channel_manager_->DestroyDataChannel(data_channel_.release());
5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (size_t i = 0; i < saved_candidates_.size(); ++i) {
5030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    delete saved_candidates_[i];
5040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  delete identity();
5060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5085aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgbool WebRtcSession::Initialize(
5095c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    const PeerConnectionFactoryInterface::Options& options,
51041c4db4baf4ecf1e3e5e91178534a2603b7dce87buildbot@webrtc.org    const MediaConstraintsInterface*  constraints,
51141c4db4baf4ecf1e3e5e91178534a2603b7dce87buildbot@webrtc.org    DTLSIdentityServiceInterface* dtls_identity_service,
51241c4db4baf4ecf1e3e5e91178534a2603b7dce87buildbot@webrtc.org    PeerConnectionInterface::IceTransportsType ice_transport) {
5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(perkj): Take |constraints| into consideration. Return false if not all
5140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // mandatory constraints can be fulfilled. Note that |constraints|
5150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // can be null.
5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool value;
517ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org
518ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org  if (options.disable_encryption) {
519ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    dtls_enabled_ = false;
520ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org  } else {
521ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    // Enable DTLS by default if |dtls_identity_service| is valid.
522ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    dtls_enabled_ = (dtls_identity_service != NULL);
523ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    // |constraints| can override the default |dtls_enabled_| value.
524ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    if (FindConstraint(
525ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org          constraints,
526ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org          MediaConstraintsInterface::kEnableDtlsSrtp,
527ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org          &value, NULL)) {
528ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org      dtls_enabled_ = value;
529ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    }
530ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org  }
531ed274f89091f7acb8cacde3cae1d69cb2a19193dsergeyu@chromium.org
5320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Enable creation of RTP data channels if the kEnableRtpDataChannels is set.
5335c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  // It takes precendence over the disable_sctp_data_channels
5345c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  // PeerConnectionFactoryInterface::Options.
5350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (FindConstraint(
5360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      constraints, MediaConstraintsInterface::kEnableRtpDataChannels,
5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      &value, NULL) && value) {
5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_INFO) << "Allowing RTP data engine.";
5390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    data_channel_type_ = cricket::DCT_RTP;
5405aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  } else {
5415aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    // DTLS has to be enabled to use SCTP.
5425c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org    if (!options.disable_sctp_data_channels && dtls_enabled_) {
5435aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      LOG(LS_INFO) << "Allowing SCTP data engine.";
5445aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      data_channel_type_ = cricket::DCT_SCTP;
5455aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    }
5460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (data_channel_type_ != cricket::DCT_NONE) {
5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    mediastream_signaling_->SetDataChannelFactory(this);
5490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
55180303b162fe139828d0661df23e03f09126508acwu@webrtc.org  // Find DSCP constraint.
55280303b162fe139828d0661df23e03f09126508acwu@webrtc.org  if (FindConstraint(
55380303b162fe139828d0661df23e03f09126508acwu@webrtc.org        constraints,
55480303b162fe139828d0661df23e03f09126508acwu@webrtc.org        MediaConstraintsInterface::kEnableDscp,
55580303b162fe139828d0661df23e03f09126508acwu@webrtc.org        &value, NULL)) {
556bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org    audio_options_.dscp.Set(value);
557bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org    video_options_.dscp.Set(value);
558bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org  }
559bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org
560bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org  // Find Suspend Below Min Bitrate constraint.
561bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org  if (FindConstraint(
562bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org          constraints,
563bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org          MediaConstraintsInterface::kEnableVideoSuspendBelowMinBitrate,
564bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org          &value,
565bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org          NULL)) {
566bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org    video_options_.suspend_below_min_bitrate.Set(value);
56780303b162fe139828d0661df23e03f09126508acwu@webrtc.org  }
56880303b162fe139828d0661df23e03f09126508acwu@webrtc.org
5693865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org  SetOptionFromOptionalConstraint(constraints,
5703865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org      MediaConstraintsInterface::kScreencastMinBitrate,
5713865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org      &video_options_.screencast_min_bitrate);
5723865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org
5733865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org  // Find constraints for cpu overuse detection.
5743865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org  SetOptionFromOptionalConstraint(constraints,
5753865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org      MediaConstraintsInterface::kCpuUnderuseThreshold,
5763865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org      &video_options_.cpu_underuse_threshold);
5773865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org  SetOptionFromOptionalConstraint(constraints,
5783865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org      MediaConstraintsInterface::kCpuOveruseThreshold,
5793865f242aa057847ca2c3728d24874882ef227eehenrike@webrtc.org      &video_options_.cpu_overuse_threshold);
5802e507b2e465fe7f63c74e04d136ec2e23810c61fbuildbot@webrtc.org  SetOptionFromOptionalConstraint(constraints,
581d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org      MediaConstraintsInterface::kCpuOveruseDetection,
582d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org      &video_options_.cpu_overuse_detection);
583d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org  SetOptionFromOptionalConstraint(constraints,
584d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org      MediaConstraintsInterface::kCpuOveruseEncodeUsage,
585d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org      &video_options_.cpu_overuse_encode_usage);
586d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org  SetOptionFromOptionalConstraint(constraints,
5872e507b2e465fe7f63c74e04d136ec2e23810c61fbuildbot@webrtc.org      MediaConstraintsInterface::kCpuUnderuseEncodeRsdThreshold,
5882e507b2e465fe7f63c74e04d136ec2e23810c61fbuildbot@webrtc.org      &video_options_.cpu_underuse_encode_rsd_threshold);
5892e507b2e465fe7f63c74e04d136ec2e23810c61fbuildbot@webrtc.org  SetOptionFromOptionalConstraint(constraints,
5902e507b2e465fe7f63c74e04d136ec2e23810c61fbuildbot@webrtc.org      MediaConstraintsInterface::kCpuOveruseEncodeRsdThreshold,
5912e507b2e465fe7f63c74e04d136ec2e23810c61fbuildbot@webrtc.org      &video_options_.cpu_overuse_encode_rsd_threshold);
592b449ff6d2befd6707e96b1db3074d1d2a49a4203buildbot@webrtc.org
593d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org  // Find payload padding constraint.
594d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org  SetOptionFromOptionalConstraint(constraints,
595d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org      MediaConstraintsInterface::kPayloadPadding,
596d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org      &video_options_.use_payload_padding);
597c97efd086dfa83409483daf9fb4daba673ebf896henrike@webrtc.org
598d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org  SetOptionFromOptionalConstraint(constraints,
599b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org      MediaConstraintsInterface::kNumUnsignalledRecvStreams,
600b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org      &video_options_.unsignalled_recv_stream_limit);
601b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org  if (video_options_.unsignalled_recv_stream_limit.IsSet()) {
602b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org    int stream_limit;
603b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org    video_options_.unsignalled_recv_stream_limit.Get(&stream_limit);
604b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org    stream_limit = rtc::_min(kMaxUnsignalledRecvStreams, stream_limit);
605b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org    stream_limit = rtc::_max(0, stream_limit);
606b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org    video_options_.unsignalled_recv_stream_limit.Set(stream_limit);
607b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org  }
608b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org
609b752f54aad7adfda3ccf223fb86f23c8b3ae7283buildbot@webrtc.org  SetOptionFromOptionalConstraint(constraints,
610d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org      MediaConstraintsInterface::kHighStartBitrate,
611d25cd982c474849f04f8a3670f3abe19ada78b11buildbot@webrtc.org      &video_options_.video_start_bitrate);
612c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org
613c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org  if (FindConstraint(
614c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org      constraints,
615c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org      MediaConstraintsInterface::kVeryHighBitrate,
616c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org      &value,
617c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org      NULL)) {
618c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org    video_options_.video_highest_bitrate.Set(
619c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org        cricket::VideoOptions::VERY_HIGH);
620c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org  } else if (FindConstraint(
621c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org      constraints,
622c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org      MediaConstraintsInterface::kHighBitrate,
623c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org      &value,
624c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org      NULL)) {
625c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org    video_options_.video_highest_bitrate.Set(
626c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org        cricket::VideoOptions::HIGH);
627c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org  }
628c8079d8b9dab16606ba32c1950d6a5c44ccbfc8ewu@webrtc.org
6295462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  SetOptionFromOptionalConstraint(constraints,
6305462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org      MediaConstraintsInterface::kCombinedAudioVideoBwe,
6315462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org      &audio_options_.combined_audio_video_bwe);
6325462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org
6330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::VideoCodec default_codec(
6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      JsepSessionDescription::kDefaultVideoCodecId,
6350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      JsepSessionDescription::kDefaultVideoCodecName,
6360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      JsepSessionDescription::kMaxVideoCodecWidth,
6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      JsepSessionDescription::kMaxVideoCodecHeight,
6380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      JsepSessionDescription::kDefaultVideoCodecFramerate,
6390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      JsepSessionDescription::kDefaultVideoCodecPreference);
6400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  channel_manager_->SetDefaultVideoEncoderConfig(
6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      cricket::VideoEncoderConfig(default_codec));
6425aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
6435aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory(
6445aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      signaling_thread(),
6455aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      channel_manager_,
6465aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      mediastream_signaling_,
6475aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      dtls_identity_service,
6485aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      this,
6495aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      id(),
6505aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      data_channel_type_,
6515528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      dtls_enabled_));
6525aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
6535aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  webrtc_session_desc_factory_->SignalIdentityReady.connect(
6545aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      this, &WebRtcSession::OnIdentityReady);
65593e7d6eb320dbb3dc5d3f0f52da9d7597697b7ebmallinath@webrtc.org
6565c9dd59107e049112f2e9a62d08a02ef4448a957wu@webrtc.org  if (options.disable_encryption) {
657ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org    webrtc_session_desc_factory_->SetSdesPolicy(cricket::SEC_DISABLED);
65893e7d6eb320dbb3dc5d3f0f52da9d7597697b7ebmallinath@webrtc.org  }
6592ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org  port_allocator()->set_candidate_filter(
6602ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org      ConvertIceTransportTypeToCandidateFilter(ice_transport));
6610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
6620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::Terminate() {
6650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetState(STATE_RECEIVEDTERMINATE);
6660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  RemoveUnusedChannelsAndTransports(NULL);
6670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(voice_channel_.get() == NULL);
6680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(video_channel_.get() == NULL);
6690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(data_channel_.get() == NULL);
6700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::StartCandidatesAllocation() {
6730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // SpeculativelyConnectTransportChannels, will call ConnectChannels method
6740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // from TransportProxy to start gathering ice candidates.
6750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SpeculativelyConnectAllTransportChannels();
6760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!saved_candidates_.empty()) {
6770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // If there are saved candidates which arrived before local description is
6780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // set, copy those to remote description.
6790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    CopySavedCandidates(remote_desc_.get());
6800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Push remote candidates present in remote description to transport channels.
6820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  UseCandidatesInSessionDescription(remote_desc_.get());
6830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
6840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
686ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.orgvoid WebRtcSession::SetSdesPolicy(cricket::SecurePolicy secure_policy) {
687ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org  webrtc_session_desc_factory_->SetSdesPolicy(secure_policy);
6880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
690ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.orgcricket::SecurePolicy WebRtcSession::SdesPolicy() const {
691ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org  return webrtc_session_desc_factory_->SdesPolicy();
6920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6942a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool WebRtcSession::GetSslRole(rtc::SSLRole* role) {
695a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  if (local_description() == NULL || remote_description() == NULL) {
696a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    LOG(LS_INFO) << "Local and Remote descriptions must be applied to get "
697a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                 << "SSL Role of the session.";
698a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    return false;
699a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
700a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
701a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // TODO(mallinath) - Return role of each transport, as role may differ from
702a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // one another.
703a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // In current implementaion we just return the role of first transport in the
704a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // transport map.
705a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  for (cricket::TransportMap::const_iterator iter = transport_proxies().begin();
706a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org       iter != transport_proxies().end(); ++iter) {
707a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    if (iter->second->impl()) {
708a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      return iter->second->impl()->GetSslRole(role);
709a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    }
710a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
711a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  return false;
712a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
713a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
7144fa2e857bf13d5b55747501e951a98a52330eed2jiayl@webrtc.orgvoid WebRtcSession::CreateOffer(
7154fa2e857bf13d5b55747501e951a98a52330eed2jiayl@webrtc.org    CreateSessionDescriptionObserver* observer,
7164fa2e857bf13d5b55747501e951a98a52330eed2jiayl@webrtc.org    const PeerConnectionInterface::RTCOfferAnswerOptions& options) {
7174fa2e857bf13d5b55747501e951a98a52330eed2jiayl@webrtc.org  webrtc_session_desc_factory_->CreateOffer(observer, options);
7185aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org}
7190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7205aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgvoid WebRtcSession::CreateAnswer(CreateSessionDescriptionObserver* observer,
7215aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org                                 const MediaConstraintsInterface* constraints) {
7225aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  webrtc_session_desc_factory_->CreateAnswer(observer, constraints);
7230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
7240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc,
7260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                        std::string* err_desc) {
7271a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org  // Takes the ownership of |desc| regardless of the result.
7282a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc);
7291a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org
730a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Validate SDP.
731a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  if (!ValidateSessionDescription(desc, cricket::CS_LOCAL, err_desc)) {
732a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    return false;
7330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Update the initiator flag if this session is the initiator.
736a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  Action action = GetAction(desc->type());
7370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (state() == STATE_INIT && action == kOffer) {
7380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    set_initiator(true);
7390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
741ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org  cricket::SecurePolicy sdes_policy =
742ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org      webrtc_session_desc_factory_->SdesPolicy();
743ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org  cricket::CryptoType crypto_required = dtls_enabled_ ?
744ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org      cricket::CT_DTLS : (sdes_policy == cricket::SEC_REQUIRED ?
745ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org          cricket::CT_SDES : cricket::CT_NONE);
7460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Update the MediaContentDescription crypto settings as per the policy set.
747ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org  UpdateSessionDescriptionSecurePolicy(crypto_required, desc->description());
7480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_local_description(desc->description()->Copy());
7501a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org  local_desc_.reset(desc_temp.release());
7510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Transport and Media channels will be created only when offer is set.
7531a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org  if (action == kOffer && !CreateChannels(local_desc_->description())) {
7540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // TODO(mallinath) - Handle CreateChannel failure, as new local description
7550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // is applied. Restore back to old description.
756f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadLocalSdp(desc->type(), kCreateChannelFailed, err_desc);
7570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Remove channel and transport proxies, if MediaContentDescription is
7600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // rejected.
7611a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org  RemoveUnusedChannelsAndTransports(local_desc_->description());
7620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
763f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  if (!UpdateSessionState(action, cricket::CS_LOCAL, err_desc)) {
7640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
7650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7662ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org
7670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Kick starting the ice candidates allocation.
7680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  StartCandidatesAllocation();
7690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Update state and SSRC of local MediaStreams and DataChannels based on the
7710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // local session description.
7720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  mediastream_signaling_->OnLocalDescriptionChanged(local_desc_.get());
7730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7742a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::SSLRole role;
775d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  if (data_channel_type_ == cricket::DCT_SCTP && GetSslRole(&role)) {
776d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    mediastream_signaling_->OnDtlsRoleReadyForSctp(role);
777d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  }
7780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (error() != cricket::BaseSession::ERROR_NONE) {
779f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadLocalSdp(desc->type(), GetSessionErrorMsg(), err_desc);
7800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
7820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
7830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc,
7850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                         std::string* err_desc) {
7861a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org  // Takes the ownership of |desc| regardless of the result.
7872a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<SessionDescriptionInterface> desc_temp(desc);
7881a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org
789a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Validate SDP.
790a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  if (!ValidateSessionDescription(desc, cricket::CS_REMOTE, err_desc)) {
791a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    return false;
7920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Transport and Media channels will be created only when offer is set.
795a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  Action action = GetAction(desc->type());
7960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (action == kOffer && !CreateChannels(desc->description())) {
7970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // TODO(mallinath) - Handle CreateChannel failure, as new local description
7980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // is applied. Restore back to old description.
799f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadRemoteSdp(desc->type(), kCreateChannelFailed, err_desc);
8000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Remove channel and transport proxies, if MediaContentDescription is
8030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // rejected.
8040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  RemoveUnusedChannelsAndTransports(desc->description());
8050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // NOTE: Candidates allocation will be initiated only when SetLocalDescription
8070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // is called.
8080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_remote_description(desc->description()->Copy());
809f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  if (!UpdateSessionState(action, cricket::CS_REMOTE, err_desc)) {
8100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
8110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Update remote MediaStreams.
8140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  mediastream_signaling_->OnRemoteDescriptionChanged(desc);
8150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (local_description() && !UseCandidatesInSessionDescription(desc)) {
816f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadRemoteSdp(desc->type(), kInvalidCandidates, err_desc);
8170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Copy all saved candidates.
8200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CopySavedCandidates(desc);
8210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // We retain all received candidates.
8225aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription(
8235aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org      remote_desc_.get(), desc);
8240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Check if this new SessionDescription contains new ice ufrag and password
8250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // that indicates the remote peer requests ice restart.
8260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ice_restart_latch_->CheckForRemoteIceRestart(remote_desc_.get(),
8270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                               desc);
8281a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org  remote_desc_.reset(desc_temp.release());
829d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org
8302a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::SSLRole role;
831d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  if (data_channel_type_ == cricket::DCT_SCTP && GetSslRole(&role)) {
832d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    mediastream_signaling_->OnDtlsRoleReadyForSctp(role);
833d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  }
834d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org
8350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (error() != cricket::BaseSession::ERROR_NONE) {
836f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadRemoteSdp(desc->type(), GetSessionErrorMsg(), err_desc);
8370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
8390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::UpdateSessionState(
8420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    Action action, cricket::ContentSource source,
8430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::string* err_desc) {
8440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If there's already a pending error then no state transition should happen.
8450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // But all call-sites should be verifying this before calling us!
8460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(error() == cricket::BaseSession::ERROR_NONE);
847f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  std::string td_err;
8480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (action == kOffer) {
849f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    if (!PushdownTransportDescription(source, cricket::CA_OFFER, &td_err)) {
850f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      return BadOfferSdp(source, MakeTdErrorString(td_err), err_desc);
8510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
8520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SetState(source == cricket::CS_LOCAL ?
8530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        STATE_SENTINITIATE : STATE_RECEIVEDINITIATE);
8540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (error() != cricket::BaseSession::ERROR_NONE) {
855f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      return BadOfferSdp(source, GetSessionErrorMsg(), err_desc);
8560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
8570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else if (action == kPrAnswer) {
858f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    if (!PushdownTransportDescription(source, cricket::CA_PRANSWER, &td_err)) {
859f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      return BadPranswerSdp(source, MakeTdErrorString(td_err), err_desc);
8600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
8610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EnableChannels();
8620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SetState(source == cricket::CS_LOCAL ?
8630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        STATE_SENTPRACCEPT : STATE_RECEIVEDPRACCEPT);
8640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (error() != cricket::BaseSession::ERROR_NONE) {
865f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      return BadPranswerSdp(source, GetSessionErrorMsg(), err_desc);
8660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
8670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else if (action == kAnswer) {
868f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    if (!PushdownTransportDescription(source, cricket::CA_ANSWER, &td_err)) {
869f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      return BadAnswerSdp(source, MakeTdErrorString(td_err), err_desc);
8700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
8710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    MaybeEnableMuxingSupport();
8720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    EnableChannels();
8730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SetState(source == cricket::CS_LOCAL ?
8740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        STATE_SENTACCEPT : STATE_RECEIVEDACCEPT);
8750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (error() != cricket::BaseSession::ERROR_NONE) {
876f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      return BadAnswerSdp(source, GetSessionErrorMsg(), err_desc);
8770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
8780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
8800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgWebRtcSession::Action WebRtcSession::GetAction(const std::string& type) {
8830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (type == SessionDescriptionInterface::kOffer) {
8840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return WebRtcSession::kOffer;
8850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else if (type == SessionDescriptionInterface::kPrAnswer) {
8860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return WebRtcSession::kPrAnswer;
8870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else if (type == SessionDescriptionInterface::kAnswer) {
8880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return WebRtcSession::kAnswer;
8890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(false && "unknown action type");
8910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return WebRtcSession::kOffer;
8920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) {
8950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (state() == STATE_INIT) {
8960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org     LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added "
8970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   << "without any offer (local or remote) "
8980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   << "session description.";
8990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org     return false;
9000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!candidate) {
9030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL";
9040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
9050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9073588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  bool valid = false;
9083588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  if (!ReadyToUseRemoteCandidate(candidate, NULL, &valid)) {
9093588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org    if (valid) {
9103588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      LOG(LS_INFO) << "ProcessIceMessage: Candidate saved";
9113588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      saved_candidates_.push_back(
9123588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org          new JsepIceCandidate(candidate->sdp_mid(),
9133588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org                               candidate->sdp_mline_index(),
9143588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org                               candidate->candidate()));
915f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org    }
9163588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org    return valid;
9170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Add this candidate to the remote session description.
9200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!remote_desc_->AddCandidate(candidate)) {
9210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "ProcessIceMessage: Candidate cannot be used";
9220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
9230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
925b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org  return UseCandidate(candidate);
9260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9282ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.orgbool WebRtcSession::SetIceTransports(
9292ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org    PeerConnectionInterface::IceTransportsType type) {
9302ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org  return port_allocator()->set_candidate_filter(
9312ca56577c4c9aaedeb70024d2012a1f519dfb201mallinath@webrtc.org        ConvertIceTransportTypeToCandidateFilter(type));
93241c4db4baf4ecf1e3e5e91178534a2603b7dce87buildbot@webrtc.org}
93341c4db4baf4ecf1e3e5e91178534a2603b7dce87buildbot@webrtc.org
934890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.orgbool WebRtcSession::GetLocalTrackIdBySsrc(uint32 ssrc, std::string* track_id) {
9350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!BaseSession::local_description())
9360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
9370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return webrtc::GetTrackIdBySsrc(
938890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      BaseSession::local_description(), ssrc, track_id);
9390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
941890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.orgbool WebRtcSession::GetRemoteTrackIdBySsrc(uint32 ssrc, std::string* track_id) {
9420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!BaseSession::remote_description())
943890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org    return false;
9440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return webrtc::GetTrackIdBySsrc(
945890e5875bea3af49a763bd49eba6d55dc4cbd190xians@webrtc.org      BaseSession::remote_description(), ssrc, track_id);
9460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
948f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstd::string WebRtcSession::BadStateErrMsg(State state) {
9490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::ostringstream desc;
950f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  desc << "Called in wrong state: " << GetStateString(state);
9510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return desc.str();
9520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9547162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgvoid WebRtcSession::SetAudioPlayout(uint32 ssrc, bool enable,
9557162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org                                    cricket::AudioRenderer* renderer) {
9560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
9570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!voice_channel_) {
9580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "SetAudioPlayout: No audio channel exists.";
9590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
9600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9617162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  if (!voice_channel_->SetRemoteRenderer(ssrc, renderer)) {
9627162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    // SetRenderer() can fail if the ssrc does not match any playout channel.
9637162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    LOG(LS_ERROR) << "SetAudioPlayout: ssrc is incorrect: " << ssrc;
9647162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    return;
9657162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  }
9660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!voice_channel_->SetOutputScaling(ssrc, enable ? 1 : 0, enable ? 1 : 0)) {
9670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Allow that SetOutputScaling fail if |enable| is false but assert
9680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // otherwise. This in the normal case when the underlying media channel has
9690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // already been deleted.
9700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(enable == false);
9710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::SetAudioSend(uint32 ssrc, bool enable,
9757162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org                                 const cricket::AudioOptions& options,
9767162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org                                 cricket::AudioRenderer* renderer) {
9770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
9780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!voice_channel_) {
9790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "SetAudioSend: No audio channel exists.";
9800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
9810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9827162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  if (!voice_channel_->SetLocalRenderer(ssrc, renderer)) {
9837162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    // SetRenderer() can fail if the ssrc does not match any send channel.
9847162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc;
9857162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    return;
9867162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  }
9870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!voice_channel_->MuteStream(ssrc, !enable)) {
9880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Allow that MuteStream fail if |enable| is false but assert otherwise.
9890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // This in the normal case when the underlying media channel has already
9900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // been deleted.
9910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(enable == false);
9920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
9930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (enable)
9950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    voice_channel_->SetChannelOptions(options);
9960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9988a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.orgvoid WebRtcSession::SetAudioPlayoutVolume(uint32 ssrc, double volume) {
9998a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
10008a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  ASSERT(volume >= 0 && volume <= 10);
10018a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  if (!voice_channel_) {
10028a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    LOG(LS_ERROR) << "SetAudioPlayoutVolume: No audio channel exists.";
10038a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    return;
10048a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  }
10058a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org
10068a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org  if (!voice_channel_->SetOutputScaling(ssrc, volume, volume))
10078a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org    ASSERT(false);
10088a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org}
10098a77f5bd83ba9386c19ff92f277c7268c1e9ef4awu@webrtc.org
10100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::SetCaptureDevice(uint32 ssrc,
10110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                     cricket::VideoCapturer* camera) {
10120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
10130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!video_channel_.get()) {
10150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // |video_channel_| doesnt't exist. Probably because the remote end doesnt't
10160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // support video.
10170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_WARNING) << "Video not used in this call.";
10180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!video_channel_->SetCapturer(ssrc, camera)) {
10210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Allow that SetCapturer fail if |camera| is NULL but assert otherwise.
10220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // This in the normal case when the underlying media channel has already
10230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // been deleted.
10240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(camera == NULL);
10250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
10280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
10290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::SetVideoPlayout(uint32 ssrc,
10310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    bool enable,
10320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    cricket::VideoRenderer* renderer) {
10330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
10340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!video_channel_) {
10350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_WARNING) << "SetVideoPlayout: No video channel exists.";
10360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
10370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!video_channel_->SetRenderer(ssrc, enable ? renderer : NULL)) {
10390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Allow that SetRenderer fail if |renderer| is NULL but assert otherwise.
10400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // This in the normal case when the underlying media channel has already
10410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // been deleted.
10420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(renderer == NULL);
10430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
10450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::SetVideoSend(uint32 ssrc, bool enable,
10470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 const cricket::VideoOptions* options) {
10480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
10490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!video_channel_) {
10500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_WARNING) << "SetVideoSend: No video channel exists.";
10510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
10520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!video_channel_->MuteStream(ssrc, !enable)) {
10540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Allow that MuteStream fail if |enable| is false but assert otherwise.
10550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // This in the normal case when the underlying media channel has already
10560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // been deleted.
10570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(enable == false);
10580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
10590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (enable && options)
10610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    video_channel_->SetChannelOptions(*options);
10620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
10630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::CanInsertDtmf(const std::string& track_id) {
10650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
10660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!voice_channel_) {
10670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists.";
10680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  uint32 send_ssrc = 0;
10710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // The Dtmf is negotiated per channel not ssrc, so we only check if the ssrc
10720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // exists.
10730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!GetAudioSsrcByTrackId(BaseSession::local_description(), track_id,
10740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             &send_ssrc)) {
10750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "CanInsertDtmf: Track does not exist: " << track_id;
10760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return voice_channel_->CanInsertDtmf();
10790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
10800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::InsertDtmf(const std::string& track_id,
10820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                               int code, int duration) {
10830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
10840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!voice_channel_) {
10850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "InsertDtmf: No audio channel exists.";
10860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  uint32 send_ssrc = 0;
10890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!VERIFY(GetAudioSsrcByTrackId(BaseSession::local_description(),
10900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                    track_id, &send_ssrc))) {
10910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "InsertDtmf: Track does not exist: " << track_id;
10920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!voice_channel_->InsertDtmf(send_ssrc, code, duration,
10950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                  cricket::DF_SEND)) {
10960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Failed to insert DTMF to channel.";
10970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
11000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgsigslot::signal0<>* WebRtcSession::GetOnDestroyedSignal() {
11030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return &SignalVoiceChannelDestroyed;
11040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1106861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.orgbool WebRtcSession::SendData(const cricket::SendDataParams& params,
11072a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                             const rtc::Buffer& payload,
1108861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org                             cricket::SendDataResult* result) {
1109861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  if (!data_channel_.get()) {
1110861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org    LOG(LS_ERROR) << "SendData called when data_channel_ is NULL.";
1111861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org    return false;
1112861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  }
1113861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  return data_channel_->SendData(params, payload, result);
1114861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org}
1115861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org
1116861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.orgbool WebRtcSession::ConnectDataChannel(DataChannel* webrtc_data_channel) {
1117861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  if (!data_channel_.get()) {
1118861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org    LOG(LS_ERROR) << "ConnectDataChannel called when data_channel_ is NULL.";
1119861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org    return false;
1120861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  }
1121861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  data_channel_->SignalReadyToSendData.connect(webrtc_data_channel,
1122861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org                                               &DataChannel::OnChannelReady);
1123861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  data_channel_->SignalDataReceived.connect(webrtc_data_channel,
1124861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org                                            &DataChannel::OnDataReceived);
1125861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  return true;
1126861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org}
1127861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org
1128861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.orgvoid WebRtcSession::DisconnectDataChannel(DataChannel* webrtc_data_channel) {
1129d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  if (!data_channel_.get()) {
1130d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    LOG(LS_ERROR) << "DisconnectDataChannel called when data_channel_ is NULL.";
1131d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    return;
1132d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  }
1133861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  data_channel_->SignalReadyToSendData.disconnect(webrtc_data_channel);
1134861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org  data_channel_->SignalDataReceived.disconnect(webrtc_data_channel);
1135861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org}
1136861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org
113719da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.orgvoid WebRtcSession::AddSctpDataStream(uint32 sid) {
1138d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  if (!data_channel_.get()) {
1139d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    LOG(LS_ERROR) << "AddDataChannelStreams called when data_channel_ is NULL.";
1140d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    return;
1141d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  }
114219da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org  data_channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(sid));
114319da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org  data_channel_->AddSendStream(cricket::StreamParams::CreateLegacy(sid));
1144d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org}
1145d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org
114619da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.orgvoid WebRtcSession::RemoveSctpDataStream(uint32 sid) {
114781f0809717fdef0375a786d36032aafdac67fd33jiayl@webrtc.org  mediastream_signaling_->RemoveSctpDataChannel(static_cast<int>(sid));
114881f0809717fdef0375a786d36032aafdac67fd33jiayl@webrtc.org
1149d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  if (!data_channel_.get()) {
1150d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    LOG(LS_ERROR) << "RemoveDataChannelStreams called when data_channel_ is "
1151d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org                  << "NULL.";
1152d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    return;
1153d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  }
115419da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org  data_channel_->RemoveRecvStream(sid);
115519da4659bfe1cd99b6b1476cae9bc74e99e0b09dsergeyu@chromium.org  data_channel_->RemoveSendStream(sid);
1156d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org}
1157d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org
11584646ae6b3bb147572c89f4aa2fd1ab5566ca3c2ewu@webrtc.orgbool WebRtcSession::ReadyToSendData() const {
11594646ae6b3bb147572c89f4aa2fd1ab5566ca3c2ewu@webrtc.org  return data_channel_.get() && data_channel_->ready_to_send_data();
11604646ae6b3bb147572c89f4aa2fd1ab5566ca3c2ewu@webrtc.org}
11614646ae6b3bb147572c89f4aa2fd1ab5566ca3c2ewu@webrtc.org
11622a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgrtc::scoped_refptr<DataChannel> WebRtcSession::CreateDataChannel(
1163861d07361a4559a72e96236f27b758a56f6f59f0wu@webrtc.org    const std::string& label,
11648485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    const InternalDataChannelInit* config) {
11650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (state() == STATE_RECEIVEDTERMINATE) {
11660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return NULL;
11670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (data_channel_type_ == cricket::DCT_NONE) {
11690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "CreateDataChannel: Data is not supported in this call.";
11700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return NULL;
11710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11728485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  InternalDataChannelInit new_config =
11738485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org      config ? (*config) : InternalDataChannelInit();
11740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (data_channel_type_ == cricket::DCT_SCTP) {
11750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (new_config.id < 0) {
11762a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      rtc::SSLRole role;
1177d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org      if (GetSslRole(&role) &&
1178d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org          !mediastream_signaling_->AllocateSctpSid(role, &new_config.id)) {
11790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LOG(LS_ERROR) << "No id can be allocated for the SCTP data channel.";
11800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return NULL;
11810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
1182d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    } else if (!mediastream_signaling_->IsSctpSidAvailable(new_config.id)) {
11830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_ERROR) << "Failed to create a SCTP data channel "
11840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    << "because the id is already in use or out of range.";
11850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return NULL;
11860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
11870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11885aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
11892a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_refptr<DataChannel> channel(DataChannel::Create(
11908485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org      this, data_channel_type_, label, new_config));
1191d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  if (channel && !mediastream_signaling_->AddDataChannel(channel))
11920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return NULL;
1193d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org
11940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return channel;
11950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgcricket::DataChannelType WebRtcSession::data_channel_type() const {
11980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return data_channel_type_;
11990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
12000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12015aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgbool WebRtcSession::IceRestartPending() const {
12025aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  return ice_restart_latch_->Get();
12035aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org}
12045aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
12055aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgvoid WebRtcSession::ResetIceRestartLatch() {
12065aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  ice_restart_latch_->Reset();
12075aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org}
12085aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
12092a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid WebRtcSession::OnIdentityReady(rtc::SSLIdentity* identity) {
12105aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  SetIdentity(identity);
12115aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org}
12125aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
12135aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgbool WebRtcSession::waiting_for_identity() const {
12145aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  return webrtc_session_desc_factory_->waiting_for_identity();
12155aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org}
12165aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
12170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::SetIceConnectionState(
12180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      PeerConnectionInterface::IceConnectionState state) {
12190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (ice_connection_state_ == state) {
12200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
12210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // ASSERT that the requested transition is allowed.  Note that
12240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // WebRtcSession does not implement "kIceConnectionClosed" (that is handled
12250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // within PeerConnection).  This switch statement should compile away when
12260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // ASSERTs are disabled.
12270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (ice_connection_state_) {
12280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case PeerConnectionInterface::kIceConnectionNew:
12290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(state == PeerConnectionInterface::kIceConnectionChecking);
12300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case PeerConnectionInterface::kIceConnectionChecking:
12320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(state == PeerConnectionInterface::kIceConnectionFailed ||
12330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             state == PeerConnectionInterface::kIceConnectionConnected);
12340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case PeerConnectionInterface::kIceConnectionConnected:
12360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(state == PeerConnectionInterface::kIceConnectionDisconnected ||
12370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             state == PeerConnectionInterface::kIceConnectionChecking ||
12380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             state == PeerConnectionInterface::kIceConnectionCompleted);
12390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case PeerConnectionInterface::kIceConnectionCompleted:
12410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(state == PeerConnectionInterface::kIceConnectionConnected ||
12420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             state == PeerConnectionInterface::kIceConnectionDisconnected);
12430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case PeerConnectionInterface::kIceConnectionFailed:
12450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(state == PeerConnectionInterface::kIceConnectionNew);
12460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case PeerConnectionInterface::kIceConnectionDisconnected:
12480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(state == PeerConnectionInterface::kIceConnectionChecking ||
12490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             state == PeerConnectionInterface::kIceConnectionConnected ||
12500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             state == PeerConnectionInterface::kIceConnectionCompleted ||
12510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org             state == PeerConnectionInterface::kIceConnectionFailed);
12520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case PeerConnectionInterface::kIceConnectionClosed:
12540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(false);
12550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
12570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ASSERT(false);
12580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ice_connection_state_ = state;
12620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (ice_observer_) {
12630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ice_observer_->OnIceConnectionChange(ice_connection_state_);
12640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
12660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::OnTransportRequestSignaling(
12680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    cricket::Transport* transport) {
12690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
12700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport->OnSignalingReady();
12710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (ice_observer_) {
12720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ice_observer_->OnIceGatheringChange(
12730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      PeerConnectionInterface::kIceGatheringGathering);
12740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
12760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::OnTransportConnecting(cricket::Transport* transport) {
12780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
12790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // start monitoring for the write state of the transport.
12800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  OnTransportWritable(transport);
12810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
12820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::OnTransportWritable(cricket::Transport* transport) {
12840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
12850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (transport->all_channels_writable()) {
1286b1ad2cd39fca8ea62e7dc512e788a414b328db7dhenrike@webrtc.org    SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected);
12870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else if (transport->HasChannels()) {
12880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // If the current state is Connected or Completed, then there were writable
12890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // channels but now there are not, so the next state must be Disconnected.
12900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (ice_connection_state_ ==
12910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            PeerConnectionInterface::kIceConnectionConnected ||
12920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ice_connection_state_ ==
12930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            PeerConnectionInterface::kIceConnectionCompleted) {
12940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      SetIceConnectionState(
12950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          PeerConnectionInterface::kIceConnectionDisconnected);
12960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
12970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
12990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1300f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.orgvoid WebRtcSession::OnTransportCompleted(cricket::Transport* transport) {
1301f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
1302f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org  SetIceConnectionState(PeerConnectionInterface::kIceConnectionCompleted);
1303f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org}
1304f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org
1305f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.orgvoid WebRtcSession::OnTransportFailed(cricket::Transport* transport) {
1306f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
1307f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org  SetIceConnectionState(PeerConnectionInterface::kIceConnectionFailed);
1308f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org}
1309f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org
13100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::OnTransportProxyCandidatesReady(
13110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    cricket::TransportProxy* proxy, const cricket::Candidates& candidates) {
13120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
13130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ProcessNewLocalCandidate(proxy->content_name(), candidates);
13140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
13150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::OnCandidatesAllocationDone() {
13170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
13180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (ice_observer_) {
13190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ice_observer_->OnIceGatheringChange(
13200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      PeerConnectionInterface::kIceGatheringComplete);
13210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ice_observer_->OnIceComplete();
13220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
13240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Enabling voice and video channel.
13260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::EnableChannels() {
13270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (voice_channel_ && !voice_channel_->enabled())
13280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    voice_channel_->Enable(true);
13290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (video_channel_ && !video_channel_->enabled())
13310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    video_channel_->Enable(true);
13320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (data_channel_.get() && !data_channel_->enabled())
13340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    data_channel_->Enable(true);
13350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
13360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::ProcessNewLocalCandidate(
13380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string& content_name,
13390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const cricket::Candidates& candidates) {
13400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  int sdp_mline_index;
13410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!GetLocalCandidateMediaIndex(content_name, &sdp_mline_index)) {
13420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "ProcessNewLocalCandidate: content name "
13430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  << content_name << " not found";
13440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
13450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (cricket::Candidates::const_iterator citer = candidates.begin();
13480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      citer != candidates.end(); ++citer) {
13490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Use content_name as the candidate media id.
13500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    JsepIceCandidate candidate(content_name, sdp_mline_index, *citer);
13510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (ice_observer_) {
13520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ice_observer_->OnIceCandidate(&candidate);
13530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (local_desc_) {
13550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      local_desc_->AddCandidate(&candidate);
13560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
13590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// Returns the media index for a local ice candidate given the content name.
13610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name,
13620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                int* sdp_mline_index) {
13630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!BaseSession::local_description() || !sdp_mline_index)
13640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
13650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool content_found = false;
13670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const ContentInfos& contents = BaseSession::local_description()->contents();
13680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (size_t index = 0; index < contents.size(); ++index) {
13690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (contents[index].name == content_name) {
13701a04b881e0ef480802fb01b4fbe9bcd5388d2c69henrike@webrtc.org      *sdp_mline_index = static_cast<int>(index);
13710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      content_found = true;
13720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
13730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return content_found;
13760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
13770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::UseCandidatesInSessionDescription(
13790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const SessionDescriptionInterface* remote_desc) {
13800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!remote_desc)
13810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
13820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool ret = true;
13833588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org
13840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (size_t m = 0; m < remote_desc->number_of_mediasections(); ++m) {
13850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const IceCandidateCollection* candidates = remote_desc->candidates(m);
13860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for  (size_t n = 0; n < candidates->count(); ++n) {
13873588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      const IceCandidateInterface* candidate = candidates->at(n);
13883588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      bool valid = false;
13893588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      if (!ReadyToUseRemoteCandidate(candidate, remote_desc, &valid)) {
13903588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org        if (valid) {
13913588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org          LOG(LS_INFO) << "UseCandidatesInSessionDescription: Candidate saved.";
13923588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org          saved_candidates_.push_back(
13933588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org              new JsepIceCandidate(candidate->sdp_mid(),
13943588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org                                   candidate->sdp_mline_index(),
13953588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org                                   candidate->candidate()));
13963588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org        }
13973588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org        continue;
13983588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      }
13993588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org
14003588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      ret = UseCandidate(candidate);
14010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!ret)
14020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        break;
14030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
14040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return ret;
14060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
14070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::UseCandidate(
14090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const IceCandidateInterface* candidate) {
14100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  size_t mediacontent_index = static_cast<size_t>(candidate->sdp_mline_index());
14120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  size_t remote_content_size =
14130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      BaseSession::remote_description()->contents().size();
14140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (mediacontent_index >= remote_content_size) {
14150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR)
14160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        << "UseRemoteCandidateInSession: Invalid candidate media index.";
14170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
14180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  cricket::ContentInfo content =
14210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      BaseSession::remote_description()->contents()[mediacontent_index];
14220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::vector<cricket::Candidate> candidates;
14230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  candidates.push_back(candidate->candidate());
14240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Invoking BaseSession method to handle remote candidates.
14250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string error;
14260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (OnRemoteCandidates(content.name, candidates, &error)) {
14270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Candidates successfully submitted for checking.
14280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew ||
14290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        ice_connection_state_ ==
14300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org            PeerConnectionInterface::kIceConnectionDisconnected) {
14310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // If state is New, then the session has just gotten its first remote ICE
14320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // candidates, so go to Checking.
14330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // If state is Disconnected, the session is re-using old candidates or
14340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // receiving additional ones, so go to Checking.
14350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // If state is Connected, stay Connected.
14360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // TODO(bemasc): If state is Connected, and the new candidates are for a
14370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // newly added transport, then the state actually _should_ move to
14380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // checking.  Add a way to distinguish that case.
14390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking);
14400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
14410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // TODO(bemasc): If state is Completed, go back to Connected.
14420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
14437ce0f9ed8df94129fddd70cdf0a53aa86d6b9d48fischman@webrtc.org    if (!error.empty()) {
14447ce0f9ed8df94129fddd70cdf0a53aa86d6b9d48fischman@webrtc.org      LOG(LS_WARNING) << error;
14457ce0f9ed8df94129fddd70cdf0a53aa86d6b9d48fischman@webrtc.org    }
14460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
14480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
14490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::RemoveUnusedChannelsAndTransports(
14510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const SessionDescription* desc) {
14525462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  // Destroy video_channel_ first since it may have a pointer to the
14535462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  // voice_channel_.
14540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::ContentInfo* video_info =
14550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      cricket::GetFirstVideoContent(desc);
14560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if ((!video_info || video_info->rejected) && video_channel_) {
14570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    mediastream_signaling_->OnVideoChannelClose();
14580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalVideoChannelDestroyed();
14590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string content_name = video_channel_->content_name();
14600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    channel_manager_->DestroyVideoChannel(video_channel_.release());
14610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    DestroyTransportProxy(content_name);
14620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14645462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  const cricket::ContentInfo* voice_info =
14655462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org      cricket::GetFirstAudioContent(desc);
14665462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  if ((!voice_info || voice_info->rejected) && voice_channel_) {
14675462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org    mediastream_signaling_->OnAudioChannelClose();
14685462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org    SignalVoiceChannelDestroyed();
14695462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org    const std::string content_name = voice_channel_->content_name();
14705462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org    channel_manager_->DestroyVoiceChannel(voice_channel_.release());
14715462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org    DestroyTransportProxy(content_name);
14725462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org  }
14735462dd96b8c4b0be60dd3110e70f4345c110044abuildbot@webrtc.org
14740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::ContentInfo* data_info =
14750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      cricket::GetFirstDataContent(desc);
14760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if ((!data_info || data_info->rejected) && data_channel_) {
14770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    mediastream_signaling_->OnDataChannelClose();
14780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalDataChannelDestroyed();
14790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string content_name = data_channel_->content_name();
14800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    channel_manager_->DestroyDataChannel(data_channel_.release());
14810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    DestroyTransportProxy(content_name);
14820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
14840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14857162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org// TODO(mallinath) - Add a correct error code if the channels are not creatued
14867162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org// due to BUNDLE is enabled but rtcp-mux is disabled.
14870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool WebRtcSession::CreateChannels(const SessionDescription* desc) {
14880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Disabling the BUNDLE flag in PortAllocator if offer disabled it.
14897162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE);
14907162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  if (state() == STATE_INIT && !bundle_enabled) {
14910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    port_allocator()->set_flags(port_allocator()->flags() &
14920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                ~cricket::PORTALLOCATOR_ENABLE_BUNDLE);
14930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Creating the media channels and transport proxies.
14960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc);
14970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (voice && !voice->rejected && !voice_channel_) {
14987162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    if (!CreateVoiceChannel(voice)) {
14990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_ERROR) << "Failed to create voice channel.";
15000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
15010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
15020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc);
15050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (video && !video->rejected && !video_channel_) {
15067162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    if (!CreateVideoChannel(video)) {
15070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_ERROR) << "Failed to create video channel.";
15080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
15090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
15100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const cricket::ContentInfo* data = cricket::GetFirstDataContent(desc);
15130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (data_channel_type_ != cricket::DCT_NONE &&
15140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      data && !data->rejected && !data_channel_.get()) {
15157162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    if (!CreateDataChannel(data)) {
15160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_ERROR) << "Failed to create data channel.";
15170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
15180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
15190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
15220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15247162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgbool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) {
15250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  voice_channel_.reset(channel_manager_->CreateVoiceChannel(
15267162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org      this, content->name, true));
152780303b162fe139828d0661df23e03f09126508acwu@webrtc.org  if (!voice_channel_.get())
152880303b162fe139828d0661df23e03f09126508acwu@webrtc.org    return false;
152980303b162fe139828d0661df23e03f09126508acwu@webrtc.org
1530bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org  voice_channel_->SetChannelOptions(audio_options_);
153180303b162fe139828d0661df23e03f09126508acwu@webrtc.org  return true;
15320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15347162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgbool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) {
15350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  video_channel_.reset(channel_manager_->CreateVideoChannel(
15367162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org      this, content->name, true, voice_channel_.get()));
153780303b162fe139828d0661df23e03f09126508acwu@webrtc.org  if (!video_channel_.get())
153880303b162fe139828d0661df23e03f09126508acwu@webrtc.org    return false;
153980303b162fe139828d0661df23e03f09126508acwu@webrtc.org
1540bf64da011cfd8fc4c0243d7c52caa6db0d298bddhenrike@webrtc.org  video_channel_->SetChannelOptions(video_options_);
154180303b162fe139828d0661df23e03f09126508acwu@webrtc.org  return true;
15420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15447162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgbool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) {
1545d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  bool sctp = (data_channel_type_ == cricket::DCT_SCTP);
15460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  data_channel_.reset(channel_manager_->CreateDataChannel(
1547d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org      this, content->name, !sctp, data_channel_type_));
15485aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  if (!data_channel_.get()) {
15495aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    return false;
15505aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  }
1551d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  if (sctp) {
1552d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org    mediastream_signaling_->OnDataTransportCreatedForSctp();
15538485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    data_channel_->SignalDataReceived.connect(
15548485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org        this, &WebRtcSession::OnDataChannelMessageReceived);
1555f365c83eeda1a21af3740b70798f6ca65c7bc182buildbot@webrtc.org    data_channel_->SignalStreamClosedRemotely.connect(
1556f365c83eeda1a21af3740b70798f6ca65c7bc182buildbot@webrtc.org        mediastream_signaling_,
1557f365c83eeda1a21af3740b70798f6ca65c7bc182buildbot@webrtc.org        &MediaStreamSignaling::OnRemoteSctpDataChannelClosed);
1558d1f631d5ec5c25dd0a63ed70d0ffa66037d8aa6awu@webrtc.org  }
15595aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  return true;
15600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid WebRtcSession::CopySavedCandidates(
15630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SessionDescriptionInterface* dest_desc) {
15640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!dest_desc) {
15650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(false);
15660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
15670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (size_t i = 0; i < saved_candidates_.size(); ++i) {
15690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    dest_desc->AddCandidate(saved_candidates_[i]);
15700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    delete saved_candidates_[i];
15710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  saved_candidates_.clear();
15730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15758485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.orgvoid WebRtcSession::OnDataChannelMessageReceived(
15768485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    cricket::DataChannel* channel,
15778485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    const cricket::ReceiveDataParams& params,
15782a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    const rtc::Buffer& payload) {
1579cc712021a90cc93a68b4e65930cd0a0ad0a88d4ewu@webrtc.org  ASSERT(data_channel_type_ == cricket::DCT_SCTP);
15808485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  if (params.type == cricket::DMT_CONTROL &&
15818485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org      mediastream_signaling_->IsSctpSidAvailable(params.ssrc)) {
15828485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    // Received CONTROL on unused sid, process as an OPEN message.
15838485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org    mediastream_signaling_->AddDataChannelFromOpenMessage(params, payload);
15840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15858485ec698cd13d65354e2f81132b5763a3d216a4henrika@webrtc.org  // otherwise ignore the message.
15860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15887162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org// Returns false if bundle is enabled and rtcp_mux is disabled.
1589a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgbool WebRtcSession::ValidateBundleSettings(const SessionDescription* desc) {
15907162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE);
15917162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  if (!bundle_enabled)
15927162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    return true;
15937162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org
15947162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  const cricket::ContentGroup* bundle_group =
15957162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org      desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE);
15967162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  ASSERT(bundle_group != NULL);
15977162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org
15987162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  const cricket::ContentInfos& contents = desc->contents();
15997162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  for (cricket::ContentInfos::const_iterator citer = contents.begin();
16007162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org       citer != contents.end(); ++citer) {
16017162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    const cricket::ContentInfo* content = (&*citer);
16027162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    ASSERT(content != NULL);
16037162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    if (bundle_group->HasContentName(content->name) &&
16047162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org        !content->rejected && content->type == cricket::NS_JINGLE_RTP) {
16057162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org      if (!HasRtcpMuxEnabled(content))
16067162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org        return false;
16077162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    }
16087162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  }
16097162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  // RTCP-MUX is enabled in all the contents.
16107162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  return true;
16117162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org}
16127162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org
16137162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.orgbool WebRtcSession::HasRtcpMuxEnabled(
16147162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org    const cricket::ContentInfo* content) {
16157162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  const cricket::MediaContentDescription* description =
16167162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org      static_cast<cricket::MediaContentDescription*>(content->description);
16177162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  return description->rtcp_mux();
16187162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org}
16197162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org
1620a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgbool WebRtcSession::ValidateSessionDescription(
1621a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    const SessionDescriptionInterface* sdesc,
1622f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    cricket::ContentSource source, std::string* err_desc) {
1623f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  std::string type;
1624a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  if (error() != cricket::BaseSession::ERROR_NONE) {
1625f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadSdp(source, type, GetSessionErrorMsg(), err_desc);
1626a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
1627a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1628a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  if (!sdesc || !sdesc->description()) {
1629f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadSdp(source, type, kInvalidSdp, err_desc);
1630a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
1631a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1632f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  type = sdesc->type();
1633a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  Action action = GetAction(sdesc->type());
1634a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  if (source == cricket::CS_LOCAL) {
1635a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    if (!ExpectSetLocalDescription(action))
1636f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      return BadLocalSdp(type, BadStateErrMsg(state()), err_desc);
1637a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  } else {
1638a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    if (!ExpectSetRemoteDescription(action))
1639f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      return BadRemoteSdp(type, BadStateErrMsg(state()), err_desc);
1640a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
1641a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1642a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Verify crypto settings.
16435528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org  std::string crypto_error;
1644ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org  if ((webrtc_session_desc_factory_->SdesPolicy() == cricket::SEC_REQUIRED ||
1645ac5a3e5f1e59174797dc60641cba617c1bf0c279henrike@webrtc.org       dtls_enabled_) &&
16465528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      !VerifyCrypto(sdesc->description(), dtls_enabled_, &crypto_error)) {
1647f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadSdp(source, type, crypto_error, err_desc);
1648a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
1649a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
16508841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org  // Verify ice-ufrag and ice-pwd.
16518841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org  if (!VerifyIceUfragPwdPresent(sdesc->description())) {
1652f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadSdp(source, type, kSdpWithoutIceUfragPwd, err_desc);
16538841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org  }
16548841d7bf4010478a4b3978ff2d181d9504b2bbe3mallinath@webrtc.org
1655a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  if (!ValidateBundleSettings(sdesc->description())) {
1656f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    return BadSdp(source, type, kBundleWithoutRtcpMux, err_desc);
1657a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
1658a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1659a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  // Verify m-lines in Answer when compared against Offer.
1660a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  if (action == kAnswer) {
1661a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    const cricket::SessionDescription* offer_desc =
1662a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org        (source == cricket::CS_LOCAL) ? remote_description()->description() :
1663a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org            local_description()->description();
1664a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    if (!VerifyMediaDescriptions(sdesc->description(), offer_desc)) {
1665f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      return BadAnswerSdp(source, kMlineMismatch, err_desc);
1666a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    }
1667a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  }
1668a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1669a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  return true;
1670a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
1671a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1672a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgbool WebRtcSession::ExpectSetLocalDescription(Action action) {
1673a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  return ((action == kOffer && state() == STATE_INIT) ||
1674a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          // update local offer
1675a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kOffer && state() == STATE_SENTINITIATE) ||
1676a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          // update the current ongoing session.
1677a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kOffer && state() == STATE_RECEIVEDACCEPT) ||
1678a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kOffer && state() == STATE_SENTACCEPT) ||
1679a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kOffer && state() == STATE_INPROGRESS) ||
1680a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          // accept remote offer
1681a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kAnswer && state() == STATE_RECEIVEDINITIATE) ||
1682a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kAnswer && state() == STATE_SENTPRACCEPT) ||
1683a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kPrAnswer && state() == STATE_RECEIVEDINITIATE) ||
1684a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kPrAnswer && state() == STATE_SENTPRACCEPT));
1685a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
1686a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1687a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.orgbool WebRtcSession::ExpectSetRemoteDescription(Action action) {
1688a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org  return ((action == kOffer && state() == STATE_INIT) ||
1689a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          // update remote offer
1690a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kOffer && state() == STATE_RECEIVEDINITIATE) ||
1691a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          // update the current ongoing session
1692a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kOffer && state() == STATE_RECEIVEDACCEPT) ||
1693a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kOffer && state() == STATE_SENTACCEPT) ||
1694a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kOffer && state() == STATE_INPROGRESS) ||
1695a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          // accept local offer
1696a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kAnswer && state() == STATE_SENTINITIATE) ||
1697a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kAnswer && state() == STATE_RECEIVEDPRACCEPT) ||
1698a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kPrAnswer && state() == STATE_SENTINITIATE) ||
1699a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org          (action == kPrAnswer && state() == STATE_RECEIVEDPRACCEPT));
1700a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org}
1701a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org
1702f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgstd::string WebRtcSession::GetSessionErrorMsg() {
1703f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  std::ostringstream desc;
1704f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  desc << kSessionError << GetErrorCodeString(error()) << ". ";
1705f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  desc << kSessionErrorDesc << error_desc() << ".";
1706f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  return desc.str();
1707f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org}
1708f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org
17093588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org// We need to check the local/remote description for the Transport instead of
17103588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org// the session, because a new Transport added during renegotiation may have
17113588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org// them unset while the session has them set from the previous negotiation.
17123588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org// Not doing so may trigger the auto generation of transport description and
17133588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org// mess up DTLS identity information, ICE credential, etc.
17143588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.orgbool WebRtcSession::ReadyToUseRemoteCandidate(
17153588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org    const IceCandidateInterface* candidate,
17163588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org    const SessionDescriptionInterface* remote_desc,
17173588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org    bool* valid) {
17183588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  *valid = true;;
17193588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  cricket::TransportProxy* transport_proxy = NULL;
17203588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org
17213588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  const SessionDescriptionInterface* current_remote_desc =
17223588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      remote_desc ? remote_desc : remote_description();
17233588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org
17243588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  if (!current_remote_desc)
17253588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org    return false;
17263588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org
17273588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  size_t mediacontent_index =
17283588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      static_cast<size_t>(candidate->sdp_mline_index());
17293588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  size_t remote_content_size =
17303588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      current_remote_desc->description()->contents().size();
17313588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  if (mediacontent_index >= remote_content_size) {
17323588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org    LOG(LS_ERROR)
17333588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org        << "ReadyToUseRemoteCandidate: Invalid candidate media index.";
17343588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org
17353588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org    *valid = false;
17363588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org    return false;
17373588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  }
17383588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org
17393588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  cricket::ContentInfo content =
17403588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      current_remote_desc->description()->contents()[mediacontent_index];
17413588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  transport_proxy = GetTransportProxy(content.name);
17423588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org
17433588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org  return transport_proxy && transport_proxy->local_description_set() &&
17443588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org      transport_proxy->remote_description_set();
17453588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org}
17463588cd9ca934134ac5512fa6afc36fcf533a0040jiayl@webrtc.org
17470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}  // namespace webrtc
1748