15976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org/* 25976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * libjingle 35976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Copyright 2012, Google Inc. 45976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 55976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * Redistribution and use in source and binary forms, with or without 65976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * modification, are permitted provided that the following conditions are met: 75976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 85976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer. 105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * this list of conditions and the following disclaimer in the documentation 125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * and/or other materials provided with the distribution. 135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * derived from this software without specific prior written permission. 155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * 165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org */ 275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/app/webrtc/webrtcsession.h" 295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <algorithm> 315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <climits> 325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include <vector> 335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/app/webrtc/jsepicecandidate.h" 355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/app/webrtc/jsepsessiondescription.h" 365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/app/webrtc/mediaconstraintsinterface.h" 375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/app/webrtc/mediastreamsignaling.h" 385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/app/webrtc/peerconnectioninterface.h" 39e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org#include "talk/app/webrtc/webrtcsessiondescriptionfactory.h" 405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/helpers.h" 415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/logging.h" 425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/base/stringencode.h" 435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/media/base/constants.h" 445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/media/base/videocapturer.h" 455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/session/media/channel.h" 465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/session/media/channelmanager.h" 475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#include "talk/session/media/mediasession.h" 485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing cricket::ContentInfo; 505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing cricket::ContentInfos; 515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing cricket::MediaContentDescription; 525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing cricket::SessionDescription; 535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgusing cricket::TransportInfo; 545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgnamespace webrtc { 565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kInternalConstraintPrefix[] = "internal"; 585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Supported MediaConstraints. 605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// DTLS-SRTP pseudo-constraints. 615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char MediaConstraintsInterface::kEnableDtlsSrtp[] = 625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "DtlsSrtpKeyAgreement"; 635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// DataChannel pseudo constraints. 645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char MediaConstraintsInterface::kEnableRtpDataChannels[] = 655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "RtpDataChannels"; 665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// This constraint is for internal use only, representing the Chrome command 675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// line flag. So it is prefixed with kInternalConstraintPrefix so JS values 685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// will be removed. 695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char MediaConstraintsInterface::kEnableSctpDataChannels[] = 705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "internalSctpDataChannels"; 715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Error messages 735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kSetLocalSdpFailed[] = "SetLocalDescription failed: "; 745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kSetRemoteSdpFailed[] = "SetRemoteDescription failed: "; 755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kCreateChannelFailed[] = "Failed to create channels."; 76c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.orgconst char kBundleWithoutRtcpMux[] = "RTCP-MUX must be enabled when BUNDLE " 77c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org "is enabled."; 785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kInvalidCandidates[] = "Description contains invalid candidates."; 795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kInvalidSdp[] = "Invalid session description."; 805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kMlineMismatch[] = 815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Offer and answer descriptions m-lines are not matching. " 825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Rejecting answer."; 835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kSdpWithoutCrypto[] = "Called with a SDP without crypto enabled."; 845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kSessionError[] = "Session error code: "; 855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kUpdateStateFailed[] = "Failed to update session state: "; 865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kPushDownOfferTDFailed[] = 875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Failed to push down offer transport description."; 885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kPushDownPranswerTDFailed[] = 895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Failed to push down pranswer transport description."; 905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgconst char kPushDownAnswerTDFailed[] = 915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org "Failed to push down answer transport description."; 925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Compares |answer| against |offer|. Comparision is done 945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// for number of m-lines in answer against offer. If matches true will be 955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// returned otherwise false. 965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool VerifyMediaDescriptions( 975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const SessionDescription* answer, const SessionDescription* offer) { 985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (offer->contents().size() != answer->contents().size()) 995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t i = 0; i < offer->contents().size(); ++i) { 1025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if ((offer->contents()[i].name) != answer->contents()[i].name) { 1035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 1075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Checks that each non-rejected content has SDES crypto keys or a DTLS 1105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// fingerprint. Mismatches, such as replying with a DTLS fingerprint to SDES 1115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// keys, will be caught in Transport negotiation, and backstopped by Channel's 1125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// |secure_required| check. 1135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool VerifyCrypto(const SessionDescription* desc) { 1145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!desc) { 1155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const ContentInfos& contents = desc->contents(); 1185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t index = 0; index < contents.size(); ++index) { 1195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const ContentInfo* cinfo = &contents[index]; 1205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (cinfo->rejected) { 1215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 1225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If the content isn't rejected, crypto must be present. 1255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const MediaContentDescription* media = 1265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<const MediaContentDescription*>(cinfo->description); 1275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const TransportInfo* tinfo = desc->GetTransportInfoByName(cinfo->name); 1285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!media || !tinfo) { 1295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Something is not right. 1305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << kInvalidSdp; 1315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (media->cryptos().empty() && 1345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org !tinfo->description.identity_fingerprint) { 1355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Crypto must be supplied. 1365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_WARNING) << "Session description must have SDES or DTLS-SRTP."; 1375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 1425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 144e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org// Forces |sdesc->crypto_required| to the appropriate state based on the 145e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org// current security policy, to ensure a failure occurs if there is an error 146e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org// in crypto negotiation. 147e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org// Called when processing the local session description. 148e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgstatic void UpdateSessionDescriptionSecurePolicy( 149e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org cricket::SecureMediaPolicy secure_policy, 150e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org SessionDescription* sdesc) { 151e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (!sdesc) { 152e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return; 153e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 1545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 155e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org // Updating the |crypto_required_| in MediaContentDescription to the 156e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org // appropriate state based on the current security policy. 157e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org for (cricket::ContentInfos::iterator iter = sdesc->contents().begin(); 158e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org iter != sdesc->contents().end(); ++iter) { 159e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (cricket::IsMediaContent(&*iter)) { 160e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org MediaContentDescription* mdesc = 161e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org static_cast<MediaContentDescription*> (iter->description); 162e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (mdesc) { 163e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org mdesc->set_crypto_required(secure_policy == cricket::SEC_REQUIRED); 164e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 165e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 166e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 1675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool GetAudioSsrcByTrackId( 1705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const SessionDescription* session_description, 1715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string& track_id, uint32 *ssrc) { 1725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::ContentInfo* audio_info = 1735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::GetFirstAudioContent(session_description); 1745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!audio_info) { 1755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "Audio not used in this call"; 1765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::MediaContentDescription* audio_content = 1805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<const cricket::MediaContentDescription*>( 1815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org audio_info->description); 1825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::StreamParams stream; 1835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!cricket::GetStreamByIds(audio_content->streams(), "", track_id, 1845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org &stream)) { 1855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 1865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 1875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *ssrc = stream.first_ssrc(); 1885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 1895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 1905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool GetTrackIdBySsrc(const SessionDescription* session_description, 1925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org uint32 ssrc, std::string* track_id) { 1935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(track_id != NULL); 1945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::StreamParams stream_out; 1965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::ContentInfo* audio_info = 1975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::GetFirstAudioContent(session_description); 1985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!audio_info) { 1995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::MediaContentDescription* audio_content = 2025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<const cricket::MediaContentDescription*>( 2035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org audio_info->description); 2045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (cricket::GetStreamBySsrc(audio_content->streams(), ssrc, &stream_out)) { 2065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *track_id = stream_out.id; 2075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::ContentInfo* video_info = 2115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::GetFirstVideoContent(session_description); 2125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!video_info) { 2135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::MediaContentDescription* video_content = 2165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org static_cast<const cricket::MediaContentDescription*>( 2175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org video_info->description); 2185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (cricket::GetStreamBySsrc(video_content->streams(), ssrc, &stream_out)) { 2205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *track_id = stream_out.id; 2215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 2225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool BadSdp(const std::string& desc, std::string* err_desc) { 2275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (err_desc) { 2285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org *err_desc = desc; 2295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << desc; 2315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 2325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool BadLocalSdp(const std::string& desc, std::string* err_desc) { 2355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string set_local_sdp_failed = kSetLocalSdpFailed; 2365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org set_local_sdp_failed.append(desc); 2375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadSdp(set_local_sdp_failed, err_desc); 2385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool BadRemoteSdp(const std::string& desc, std::string* err_desc) { 2415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string set_remote_sdp_failed = kSetRemoteSdpFailed; 2425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org set_remote_sdp_failed.append(desc); 2435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadSdp(set_remote_sdp_failed, err_desc); 2445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool BadSdp(cricket::ContentSource source, 2475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string& desc, std::string* err_desc) { 2485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (source == cricket::CS_LOCAL) { 2495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadLocalSdp(desc, err_desc); 2505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 2515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadRemoteSdp(desc, err_desc); 2525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic std::string SessionErrorMsg(cricket::BaseSession::Error error) { 2565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::ostringstream desc; 2575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org desc << kSessionError << error; 2585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return desc.str(); 2595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define GET_STRING_OF_STATE(state) \ 2625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case cricket::BaseSession::state: \ 2635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org result = #state; \ 2645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 2655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic std::string GetStateString(cricket::BaseSession::State state) { 2675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string result; 2685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (state) { 2695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_INIT) 2705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_SENTINITIATE) 2715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_RECEIVEDINITIATE) 2725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_SENTPRACCEPT) 2735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_SENTACCEPT) 2745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_RECEIVEDPRACCEPT) 2755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_RECEIVEDACCEPT) 2765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_SENTMODIFY) 2775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_RECEIVEDMODIFY) 2785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_SENTREJECT) 2795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_RECEIVEDREJECT) 2805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_SENTREDIRECT) 2815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_SENTTERMINATE) 2825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_RECEIVEDTERMINATE) 2835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_INPROGRESS) 2845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_STATE(STATE_DEINIT) 2855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org default: 2865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(false); 2875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 2885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 2895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return result; 2905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 2915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org#define GET_STRING_OF_ERROR(err) \ 2935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case cricket::BaseSession::err: \ 2945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org result = #err; \ 2955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 2965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 2975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic std::string GetErrorString(cricket::BaseSession::Error err) { 2985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string result; 2995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (err) { 3005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_ERROR(ERROR_NONE) 3015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_ERROR(ERROR_TIME) 3025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_ERROR(ERROR_RESPONSE) 3035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_ERROR(ERROR_NETWORK) 3045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_ERROR(ERROR_CONTENT) 3055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org GET_STRING_OF_ERROR(ERROR_TRANSPORT) 3065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org default: 3075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(false); 3085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 3095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return result; 3115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstatic bool SetSessionStateFailed(cricket::ContentSource source, 3145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::BaseSession::Error err, 3155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string* err_desc) { 3165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string set_state_err = kUpdateStateFailed; 3175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org set_state_err.append(GetErrorString(err)); 3185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadSdp(source, set_state_err, err_desc); 3195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Help class used to remember if a a remote peer has requested ice restart by 3225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// by sending a description with new ice ufrag and password. 3235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgclass IceRestartAnswerLatch { 3245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org public: 3255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org IceRestartAnswerLatch() : ice_restart_(false) { } 3265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 327e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org // Returns true if CheckForRemoteIceRestart has been called with a new session 328e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org // description where ice password and ufrag has changed since last time 329e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org // Reset() was called. 330e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org bool Get() const { 331e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return ice_restart_; 332e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 333e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 334e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org void Reset() { 3355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (ice_restart_) { 3365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_restart_ = false; 3375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org void CheckForRemoteIceRestart( 3415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const SessionDescriptionInterface* old_desc, 3425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const SessionDescriptionInterface* new_desc) { 3435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!old_desc || new_desc->type() != SessionDescriptionInterface::kOffer) { 3445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 3455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const SessionDescription* new_sd = new_desc->description(); 3475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const SessionDescription* old_sd = old_desc->description(); 3485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const ContentInfos& contents = new_sd->contents(); 3495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t index = 0; index < contents.size(); ++index) { 3505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const ContentInfo* cinfo = &contents[index]; 3515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (cinfo->rejected) { 3525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 3535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If the content isn't rejected, check if ufrag and password has 3555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // changed. 3565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::TransportDescription* new_transport_desc = 3575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org new_sd->GetTransportDescriptionByName(cinfo->name); 3585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::TransportDescription* old_transport_desc = 3595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org old_sd->GetTransportDescriptionByName(cinfo->name); 3605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!new_transport_desc || !old_transport_desc) { 3615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // No transport description exist. This is not an ice restart. 3625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org continue; 3635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (new_transport_desc->ice_pwd != old_transport_desc->ice_pwd && 3655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org new_transport_desc->ice_ufrag != old_transport_desc->ice_ufrag) { 3665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_INFO) << "Remote peer request ice restart."; 3675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_restart_ = true; 3685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 3695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 3725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org private: 3745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool ice_restart_; 3755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org}; 3765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 377e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgWebRtcSession::WebRtcSession( 378e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org cricket::ChannelManager* channel_manager, 379e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org talk_base::Thread* signaling_thread, 380e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org talk_base::Thread* worker_thread, 381e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org cricket::PortAllocator* port_allocator, 382e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org MediaStreamSignaling* mediastream_signaling) 3835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org : cricket::BaseSession(signaling_thread, worker_thread, port_allocator, 3845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org talk_base::ToString(talk_base::CreateRandomId64() & 3855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LLONG_MAX), 3865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::NS_JINGLE_RTP, false), 3875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // RFC 3264: The numeric value of the session id and version in the 3885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // o line MUST be representable with a "64 bit signed integer". 3895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Due to this constraint session id |sid_| is max limited to LLONG_MAX. 3905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org channel_manager_(channel_manager), 3915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org mediastream_signaling_(mediastream_signaling), 3925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_observer_(NULL), 3935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_connection_state_(PeerConnectionInterface::kIceConnectionNew), 3945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org older_version_remote_peer_(false), 3955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org data_channel_type_(cricket::DCT_NONE), 3965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_restart_latch_(new IceRestartAnswerLatch) { 3975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 3985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 3995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgWebRtcSession::~WebRtcSession() { 4005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (voice_channel_.get()) { 4015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalVoiceChannelDestroyed(); 4025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org channel_manager_->DestroyVoiceChannel(voice_channel_.release()); 4035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (video_channel_.get()) { 4055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalVideoChannelDestroyed(); 4065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org channel_manager_->DestroyVideoChannel(video_channel_.release()); 4075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (data_channel_.get()) { 4095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalDataChannelDestroyed(); 4105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org channel_manager_->DestroyDataChannel(data_channel_.release()); 4115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t i = 0; i < saved_candidates_.size(); ++i) { 4135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete saved_candidates_[i]; 4145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete identity(); 4165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 418e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgbool WebRtcSession::Initialize( 419e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org const MediaConstraintsInterface* constraints, 420e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org DTLSIdentityServiceInterface* dtls_identity_service) { 4215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO(perkj): Take |constraints| into consideration. Return false if not all 4225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // mandatory constraints can be fulfilled. Note that |constraints| 4235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // can be null. 4245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool value; 4255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Enable creation of RTP data channels if the kEnableRtpDataChannels is set. 4265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // It takes precendence over the kEnableSctpDataChannels constraint. 4275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (FindConstraint( 4285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org constraints, MediaConstraintsInterface::kEnableRtpDataChannels, 4295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org &value, NULL) && value) { 4305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_INFO) << "Allowing RTP data engine."; 4315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org data_channel_type_ = cricket::DCT_RTP; 432e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } else { 433e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org bool sctp_enabled = FindConstraint( 434e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org constraints, 435e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org MediaConstraintsInterface::kEnableSctpDataChannels, 436e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org &value, NULL) && value; 437e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org bool dtls_enabled = FindConstraint( 438e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org constraints, 439e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org MediaConstraintsInterface::kEnableDtlsSrtp, 440e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org &value, NULL) && value; 441e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 442e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org // DTLS has to be enabled to use SCTP. 443e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (sctp_enabled && dtls_enabled) { 444e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org LOG(LS_INFO) << "Allowing SCTP data engine."; 445e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org data_channel_type_ = cricket::DCT_SCTP; 446e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 4475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (data_channel_type_ != cricket::DCT_NONE) { 4495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org mediastream_signaling_->SetDataChannelFactory(this); 4505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::VideoCodec default_codec( 4535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org JsepSessionDescription::kDefaultVideoCodecId, 4545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org JsepSessionDescription::kDefaultVideoCodecName, 4555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org JsepSessionDescription::kMaxVideoCodecWidth, 4565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org JsepSessionDescription::kMaxVideoCodecHeight, 4575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org JsepSessionDescription::kDefaultVideoCodecFramerate, 4585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org JsepSessionDescription::kDefaultVideoCodecPreference); 4595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org channel_manager_->SetDefaultVideoEncoderConfig( 4605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::VideoEncoderConfig(default_codec)); 461e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 462e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org webrtc_session_desc_factory_.reset(new WebRtcSessionDescriptionFactory( 463e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org signaling_thread(), 464e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org channel_manager_, 465e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org mediastream_signaling_, 466e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org dtls_identity_service, 467e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org this, 468e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org id(), 469e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org data_channel_type_, 470e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org constraints)); 471e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 472e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org webrtc_session_desc_factory_->SignalIdentityReady.connect( 473e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org this, &WebRtcSession::OnIdentityReady); 4745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 4755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::Terminate() { 4785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetState(STATE_RECEIVEDTERMINATE); 4795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org RemoveUnusedChannelsAndTransports(NULL); 4805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(voice_channel_.get() == NULL); 4815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(video_channel_.get() == NULL); 4825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(data_channel_.get() == NULL); 4835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::StartCandidatesAllocation() { 4865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // SpeculativelyConnectTransportChannels, will call ConnectChannels method 4875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // from TransportProxy to start gathering ice candidates. 4885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SpeculativelyConnectAllTransportChannels(); 4895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!saved_candidates_.empty()) { 4905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If there are saved candidates which arrived before local description is 4915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // set, copy those to remote description. 4925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CopySavedCandidates(remote_desc_.get()); 4935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 4945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Push remote candidates present in remote description to transport channels. 4955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org UseCandidatesInSessionDescription(remote_desc_.get()); 4965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 4975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 4985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 4995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::set_secure_policy( 5005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::SecureMediaPolicy secure_policy) { 501e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org webrtc_session_desc_factory_->set_secure(secure_policy); 5025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 504e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgcricket::SecureMediaPolicy WebRtcSession::secure_policy() const { 505e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return webrtc_session_desc_factory_->secure(); 5065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 508e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgvoid WebRtcSession::CreateOffer(CreateSessionDescriptionObserver* observer, 509e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org const MediaConstraintsInterface* constraints) { 510e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org webrtc_session_desc_factory_->CreateOffer(observer, constraints); 511e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org} 5125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 513e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgvoid WebRtcSession::CreateAnswer(CreateSessionDescriptionObserver* observer, 514e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org const MediaConstraintsInterface* constraints) { 515e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org webrtc_session_desc_factory_->CreateAnswer(observer, constraints); 5165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::SetLocalDescription(SessionDescriptionInterface* desc, 5195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string* err_desc) { 520e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org cricket::SecureMediaPolicy secure_policy = 521e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org webrtc_session_desc_factory_->secure(); 522b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org // Takes the ownership of |desc| regardless of the result. 523b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org talk_base::scoped_ptr<SessionDescriptionInterface> desc_temp(desc); 524b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org 5255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error() != cricket::BaseSession::ERROR_NONE) { 5265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadLocalSdp(SessionErrorMsg(error()), err_desc); 5275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!desc || !desc->description()) { 5305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadLocalSdp(kInvalidSdp, err_desc); 5315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 532c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org 533c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (!VerifyBundleSettings(desc->description())) { 534c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return BadLocalSdp(kBundleWithoutRtcpMux, err_desc); 535c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org } 536c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org 5375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Action action = GetAction(desc->type()); 5385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!ExpectSetLocalDescription(action)) { 5395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string type = desc->type(); 5405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadLocalSdp(BadStateErrMsg(type, state()), err_desc); 5415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 542e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (secure_policy == cricket::SEC_REQUIRED && 5435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org !VerifyCrypto(desc->description())) { 5445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadLocalSdp(kSdpWithoutCrypto, err_desc); 5455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (action == kAnswer && !VerifyMediaDescriptions( 5475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org desc->description(), remote_description()->description())) { 5485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadLocalSdp(kMlineMismatch, err_desc); 5495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Update the initiator flag if this session is the initiator. 5525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (state() == STATE_INIT && action == kOffer) { 5535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org set_initiator(true); 5545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Update the MediaContentDescription crypto settings as per the policy set. 557e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org UpdateSessionDescriptionSecurePolicy(secure_policy, desc->description()); 5585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org set_local_description(desc->description()->Copy()); 560b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org local_desc_.reset(desc_temp.release()); 5615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Transport and Media channels will be created only when offer is set. 563b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org if (action == kOffer && !CreateChannels(local_desc_->description())) { 5645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO(mallinath) - Handle CreateChannel failure, as new local description 5655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // is applied. Restore back to old description. 5665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadLocalSdp(kCreateChannelFailed, err_desc); 5675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Remove channel and transport proxies, if MediaContentDescription is 5705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // rejected. 571b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org RemoveUnusedChannelsAndTransports(local_desc_->description()); 5725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!UpdateSessionState(action, cricket::CS_LOCAL, 574b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org local_desc_->description(), err_desc)) { 5755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 5765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Kick starting the ice candidates allocation. 5785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org StartCandidatesAllocation(); 5795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Update state and SSRC of local MediaStreams and DataChannels based on the 5815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // local session description. 5825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org mediastream_signaling_->OnLocalDescriptionChanged(local_desc_.get()); 5835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error() != cricket::BaseSession::ERROR_NONE) { 5855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadLocalSdp(SessionErrorMsg(error()), err_desc); 5865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 5875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 5885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 5895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 5905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::SetRemoteDescription(SessionDescriptionInterface* desc, 5915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string* err_desc) { 592e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org cricket::SecureMediaPolicy secure_policy = 593e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org webrtc_session_desc_factory_->secure(); 594b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org // Takes the ownership of |desc| regardless of the result. 595b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org talk_base::scoped_ptr<SessionDescriptionInterface> desc_temp(desc); 596b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org 5975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error() != cricket::BaseSession::ERROR_NONE) { 5985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadRemoteSdp(SessionErrorMsg(error()), err_desc); 5995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!desc || !desc->description()) { 6025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadRemoteSdp(kInvalidSdp, err_desc); 6035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 604c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org 605c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (!VerifyBundleSettings(desc->description())) { 606c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return BadRemoteSdp(kBundleWithoutRtcpMux, err_desc); 607c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org } 608c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org 6095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Action action = GetAction(desc->type()); 6105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!ExpectSetRemoteDescription(action)) { 6115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string type = desc->type(); 6125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadRemoteSdp(BadStateErrMsg(type, state()), err_desc); 6135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (action == kAnswer && !VerifyMediaDescriptions( 6165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org desc->description(), local_description()->description())) { 6175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadRemoteSdp(kMlineMismatch, err_desc); 6185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 620e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (secure_policy == cricket::SEC_REQUIRED && 6215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org !VerifyCrypto(desc->description())) { 6225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadRemoteSdp(kSdpWithoutCrypto, err_desc); 6235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Transport and Media channels will be created only when offer is set. 6265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (action == kOffer && !CreateChannels(desc->description())) { 6275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO(mallinath) - Handle CreateChannel failure, as new local description 6285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // is applied. Restore back to old description. 6295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadRemoteSdp(kCreateChannelFailed, err_desc); 6305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Remove channel and transport proxies, if MediaContentDescription is 6335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // rejected. 6345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org RemoveUnusedChannelsAndTransports(desc->description()); 6355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // NOTE: Candidates allocation will be initiated only when SetLocalDescription 6375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // is called. 6385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org set_remote_description(desc->description()->Copy()); 6395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!UpdateSessionState(action, cricket::CS_REMOTE, 6405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org desc->description(), err_desc)) { 6415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 6425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Update remote MediaStreams. 6455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org mediastream_signaling_->OnRemoteDescriptionChanged(desc); 6465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (local_description() && !UseCandidatesInSessionDescription(desc)) { 6475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadRemoteSdp(kInvalidCandidates, err_desc); 6485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Copy all saved candidates. 6515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org CopySavedCandidates(desc); 6525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // We retain all received candidates. 653e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org WebRtcSessionDescriptionFactory::CopyCandidatesFromSessionDescription( 654e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org remote_desc_.get(), desc); 6555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Check if this new SessionDescription contains new ice ufrag and password 6565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // that indicates the remote peer requests ice restart. 6575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_restart_latch_->CheckForRemoteIceRestart(remote_desc_.get(), 6585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org desc); 659b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org remote_desc_.reset(desc_temp.release()); 6605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error() != cricket::BaseSession::ERROR_NONE) { 6615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadRemoteSdp(SessionErrorMsg(error()), err_desc); 6625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 6645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 6655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 6665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::UpdateSessionState( 6675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org Action action, cricket::ContentSource source, 6685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::SessionDescription* desc, 6695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string* err_desc) { 6705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If there's already a pending error then no state transition should happen. 6715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // But all call-sites should be verifying this before calling us! 6725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(error() == cricket::BaseSession::ERROR_NONE); 6735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (action == kOffer) { 6745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!PushdownTransportDescription(source, cricket::CA_OFFER)) { 6755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadSdp(source, kPushDownOfferTDFailed, err_desc); 6765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetState(source == cricket::CS_LOCAL ? 6785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org STATE_SENTINITIATE : STATE_RECEIVEDINITIATE); 6795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error() != cricket::BaseSession::ERROR_NONE) { 6805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SetSessionStateFailed(source, error(), err_desc); 6815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (action == kPrAnswer) { 6835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!PushdownTransportDescription(source, cricket::CA_PRANSWER)) { 6845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadSdp(source, kPushDownPranswerTDFailed, err_desc); 6855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org EnableChannels(); 6875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetState(source == cricket::CS_LOCAL ? 6885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org STATE_SENTPRACCEPT : STATE_RECEIVEDPRACCEPT); 6895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error() != cricket::BaseSession::ERROR_NONE) { 6905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SetSessionStateFailed(source, error(), err_desc); 6915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (action == kAnswer) { 6935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!PushdownTransportDescription(source, cricket::CA_ANSWER)) { 6945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return BadSdp(source, kPushDownAnswerTDFailed, err_desc); 6955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 6965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org MaybeEnableMuxingSupport(); 6975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org EnableChannels(); 6985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetState(source == cricket::CS_LOCAL ? 6995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org STATE_SENTACCEPT : STATE_RECEIVEDACCEPT); 7005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (error() != cricket::BaseSession::ERROR_NONE) { 7015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return SetSessionStateFailed(source, error(), err_desc); 7025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 7055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgWebRtcSession::Action WebRtcSession::GetAction(const std::string& type) { 7085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (type == SessionDescriptionInterface::kOffer) { 7095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return WebRtcSession::kOffer; 7105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (type == SessionDescriptionInterface::kPrAnswer) { 7115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return WebRtcSession::kPrAnswer; 7125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (type == SessionDescriptionInterface::kAnswer) { 7135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return WebRtcSession::kAnswer; 7145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(false && "unknown action type"); 7165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return WebRtcSession::kOffer; 7175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::ProcessIceMessage(const IceCandidateInterface* candidate) { 7205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (state() == STATE_INIT) { 7215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "ProcessIceMessage: ICE candidates can't be added " 7225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << "without any offer (local or remote) " 7235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << "session description."; 7245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 7255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!candidate) { 7285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "ProcessIceMessage: Candidate is NULL"; 7295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 7305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!local_description() || !remote_description()) { 7335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_INFO) << "ProcessIceMessage: Remote description not set, " 7345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << "save the candidate for later use."; 7355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org saved_candidates_.push_back( 7365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org new JsepIceCandidate(candidate->sdp_mid(), candidate->sdp_mline_index(), 7375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org candidate->candidate())); 7385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 7395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Add this candidate to the remote session description. 7425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!remote_desc_->AddCandidate(candidate)) { 7435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "ProcessIceMessage: Candidate cannot be used"; 7445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 7455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return UseCandidatesInSessionDescription(remote_desc_.get()); 7485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::GetTrackIdBySsrc(uint32 ssrc, std::string* id) { 7515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (GetLocalTrackId(ssrc, id)) { 7525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (GetRemoteTrackId(ssrc, id)) { 7535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_WARNING) << "SSRC " << ssrc 7545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << " exists in both local and remote descriptions"; 7555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; // We return the remote track id. 7565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 7585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 7595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return GetRemoteTrackId(ssrc, id); 7605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 7615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::GetLocalTrackId(uint32 ssrc, std::string* track_id) { 7645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!BaseSession::local_description()) 7655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 7665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return webrtc::GetTrackIdBySsrc( 7675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org BaseSession::local_description(), ssrc, track_id); 7685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::GetRemoteTrackId(uint32 ssrc, std::string* track_id) { 7715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!BaseSession::remote_description()) 7725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 7735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return webrtc::GetTrackIdBySsrc( 7745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org BaseSession::remote_description(), ssrc, track_id); 7755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 7775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgstd::string WebRtcSession::BadStateErrMsg( 7785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string& type, State state) { 7795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::ostringstream desc; 7805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org desc << "Called with type in wrong state, " 7815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << "type: " << type << " state: " << GetStateString(state); 7825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return desc.str(); 7835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 7845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 785c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.orgvoid WebRtcSession::SetAudioPlayout(uint32 ssrc, bool enable, 786c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org cricket::AudioRenderer* renderer) { 7875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 7885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!voice_channel_) { 7895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "SetAudioPlayout: No audio channel exists."; 7905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 7915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 792c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (!voice_channel_->SetRemoteRenderer(ssrc, renderer)) { 793c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org // SetRenderer() can fail if the ssrc does not match any playout channel. 794c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org LOG(LS_ERROR) << "SetAudioPlayout: ssrc is incorrect: " << ssrc; 795c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return; 796c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org } 7975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!voice_channel_->SetOutputScaling(ssrc, enable ? 1 : 0, enable ? 1 : 0)) { 7985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Allow that SetOutputScaling fail if |enable| is false but assert 7995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // otherwise. This in the normal case when the underlying media channel has 8005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // already been deleted. 8015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(enable == false); 8025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::SetAudioSend(uint32 ssrc, bool enable, 806c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org const cricket::AudioOptions& options, 807c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org cricket::AudioRenderer* renderer) { 8085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 8095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!voice_channel_) { 8105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "SetAudioSend: No audio channel exists."; 8115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 8125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 813c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (!voice_channel_->SetLocalRenderer(ssrc, renderer)) { 814c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org // SetRenderer() can fail if the ssrc does not match any send channel. 815c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org LOG(LS_ERROR) << "SetAudioSend: ssrc is incorrect: " << ssrc; 816c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return; 817c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org } 8185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!voice_channel_->MuteStream(ssrc, !enable)) { 8195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Allow that MuteStream fail if |enable| is false but assert otherwise. 8205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // This in the normal case when the underlying media channel has already 8215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // been deleted. 8225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(enable == false); 8235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 8245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (enable) 8265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org voice_channel_->SetChannelOptions(options); 8275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::SetCaptureDevice(uint32 ssrc, 8305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::VideoCapturer* camera) { 8315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 8325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!video_channel_.get()) { 8345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // |video_channel_| doesnt't exist. Probably because the remote end doesnt't 8355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // support video. 8365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_WARNING) << "Video not used in this call."; 8375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 8385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!video_channel_->SetCapturer(ssrc, camera)) { 8405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Allow that SetCapturer fail if |camera| is NULL but assert otherwise. 8415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // This in the normal case when the underlying media channel has already 8425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // been deleted. 8435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(camera == NULL); 8445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 8455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 8475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::SetVideoPlayout(uint32 ssrc, 8505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool enable, 8515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::VideoRenderer* renderer) { 8525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 8535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!video_channel_) { 8545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_WARNING) << "SetVideoPlayout: No video channel exists."; 8555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 8565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!video_channel_->SetRenderer(ssrc, enable ? renderer : NULL)) { 8585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Allow that SetRenderer fail if |renderer| is NULL but assert otherwise. 8595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // This in the normal case when the underlying media channel has already 8605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // been deleted. 8615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(renderer == NULL); 8625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::SetVideoSend(uint32 ssrc, bool enable, 8665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::VideoOptions* options) { 8675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 8685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!video_channel_) { 8695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_WARNING) << "SetVideoSend: No video channel exists."; 8705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 8715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!video_channel_->MuteStream(ssrc, !enable)) { 8735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Allow that MuteStream fail if |enable| is false but assert otherwise. 8745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // This in the normal case when the underlying media channel has already 8755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // been deleted. 8765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(enable == false); 8775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 8785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (enable && options) 8805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org video_channel_->SetChannelOptions(*options); 8815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 8835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::CanInsertDtmf(const std::string& track_id) { 8845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 8855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!voice_channel_) { 8865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "CanInsertDtmf: No audio channel exists."; 8875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 8885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org uint32 send_ssrc = 0; 8905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // The Dtmf is negotiated per channel not ssrc, so we only check if the ssrc 8915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // exists. 8925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!GetAudioSsrcByTrackId(BaseSession::local_description(), track_id, 8935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org &send_ssrc)) { 8945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "CanInsertDtmf: Track does not exist: " << track_id; 8955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 8965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 8975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return voice_channel_->CanInsertDtmf(); 8985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 8995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 9005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::InsertDtmf(const std::string& track_id, 9015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int code, int duration) { 9025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 9035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!voice_channel_) { 9045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "InsertDtmf: No audio channel exists."; 9055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 9065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 9075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org uint32 send_ssrc = 0; 9085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!VERIFY(GetAudioSsrcByTrackId(BaseSession::local_description(), 9095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org track_id, &send_ssrc))) { 9105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "InsertDtmf: Track does not exist: " << track_id; 9115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 9125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 9135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!voice_channel_->InsertDtmf(send_ssrc, code, duration, 9145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::DF_SEND)) { 9155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "Failed to insert DTMF to channel."; 9165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 9175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 9185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 9195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 9205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 9215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgsigslot::signal0<>* WebRtcSession::GetOnDestroyedSignal() { 9225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return &SignalVoiceChannelDestroyed; 9235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 9245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 9255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgtalk_base::scoped_refptr<DataChannel> WebRtcSession::CreateDataChannel( 9265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string& label, 9275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const DataChannelInit* config) { 9285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (state() == STATE_RECEIVEDTERMINATE) { 9295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 9305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 9315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (data_channel_type_ == cricket::DCT_NONE) { 9325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "CreateDataChannel: Data is not supported in this call."; 9335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 9345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 9355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org DataChannelInit new_config = config ? (*config) : DataChannelInit(); 9365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 9375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (data_channel_type_ == cricket::DCT_SCTP) { 9385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (new_config.id < 0) { 9395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!mediastream_signaling_->AllocateSctpId(&new_config.id)) { 9405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "No id can be allocated for the SCTP data channel."; 9415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 9425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 9435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (!mediastream_signaling_->IsSctpIdAvailable(new_config.id)) { 9445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "Failed to create a SCTP data channel " 9455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << "because the id is already in use or out of range."; 9465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 9475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 9485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 949e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 9505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org talk_base::scoped_refptr<DataChannel> channel( 9515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org DataChannel::Create(this, label, &new_config)); 9525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (channel == NULL) 9535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 9545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!mediastream_signaling_->AddDataChannel(channel)) 9555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return NULL; 956e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (data_channel_type_ == cricket::DCT_SCTP) { 957e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (config == NULL) { 958e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org LOG(LS_WARNING) << "Could not send data channel OPEN message" 959e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org << " because of NULL config."; 960e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return NULL; 961e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 962e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (data_channel_.get()) { 963e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org channel->SetReceiveSsrc(new_config.id); 964e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org channel->SetSendSsrc(new_config.id); 965e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org channel->ConnectToDataSession(); 966e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 967e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (!config->negotiated) { 968e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org talk_base::Buffer *payload = new talk_base::Buffer; 969e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (!mediastream_signaling_->WriteDataChannelOpenMessage( 970e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org label, *config, payload)) { 971e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org LOG(LS_WARNING) << "Could not write data channel OPEN message"; 972e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 973e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org // SendControl may queue the message until the data channel's set up, 974e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org // or congestion clears. 975e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org channel->SendControl(payload); 976e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 977e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 9785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return channel; 9795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 9805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 9815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgcricket::DataChannelType WebRtcSession::data_channel_type() const { 9825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return data_channel_type_; 9835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 9845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 985e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgbool WebRtcSession::IceRestartPending() const { 986e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return ice_restart_latch_->Get(); 987e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org} 988e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 989e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgvoid WebRtcSession::ResetIceRestartLatch() { 990e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org ice_restart_latch_->Reset(); 991e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org} 992e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 993e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgvoid WebRtcSession::OnIdentityReady(talk_base::SSLIdentity* identity) { 994e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org SetIdentity(identity); 995e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org} 996e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 997e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgbool WebRtcSession::waiting_for_identity() const { 998e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return webrtc_session_desc_factory_->waiting_for_identity(); 999e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org} 1000e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 10015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::SetIceConnectionState( 10025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PeerConnectionInterface::IceConnectionState state) { 10035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (ice_connection_state_ == state) { 10045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 10055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 10065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 10075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // ASSERT that the requested transition is allowed. Note that 10085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // WebRtcSession does not implement "kIceConnectionClosed" (that is handled 10095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // within PeerConnection). This switch statement should compile away when 10105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // ASSERTs are disabled. 10115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org switch (ice_connection_state_) { 10125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case PeerConnectionInterface::kIceConnectionNew: 10135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(state == PeerConnectionInterface::kIceConnectionChecking); 10145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 10155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case PeerConnectionInterface::kIceConnectionChecking: 10165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(state == PeerConnectionInterface::kIceConnectionFailed || 10175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state == PeerConnectionInterface::kIceConnectionConnected); 10185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 10195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case PeerConnectionInterface::kIceConnectionConnected: 10205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(state == PeerConnectionInterface::kIceConnectionDisconnected || 10215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state == PeerConnectionInterface::kIceConnectionChecking || 10225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state == PeerConnectionInterface::kIceConnectionCompleted); 10235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 10245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case PeerConnectionInterface::kIceConnectionCompleted: 10255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(state == PeerConnectionInterface::kIceConnectionConnected || 10265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state == PeerConnectionInterface::kIceConnectionDisconnected); 10275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 10285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case PeerConnectionInterface::kIceConnectionFailed: 10295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(state == PeerConnectionInterface::kIceConnectionNew); 10305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 10315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case PeerConnectionInterface::kIceConnectionDisconnected: 10325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(state == PeerConnectionInterface::kIceConnectionChecking || 10335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state == PeerConnectionInterface::kIceConnectionConnected || 10345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state == PeerConnectionInterface::kIceConnectionCompleted || 10355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org state == PeerConnectionInterface::kIceConnectionFailed); 10365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 10375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org case PeerConnectionInterface::kIceConnectionClosed: 10385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(false); 10395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 10405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org default: 10415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(false); 10425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 10435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 10445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 10455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_connection_state_ = state; 10465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (ice_observer_) { 10475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_observer_->OnIceConnectionChange(ice_connection_state_); 10485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 10495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 10505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 10515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::OnTransportRequestSignaling( 10525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::Transport* transport) { 10535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 10545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org transport->OnSignalingReady(); 10555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (ice_observer_) { 10565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_observer_->OnIceGatheringChange( 10575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PeerConnectionInterface::kIceGatheringGathering); 10585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 10595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 10605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 10615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::OnTransportConnecting(cricket::Transport* transport) { 10625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 10635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // start monitoring for the write state of the transport. 10645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org OnTransportWritable(transport); 10655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 10665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 10675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::OnTransportWritable(cricket::Transport* transport) { 10685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 10695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO(bemasc): Expose more API from Transport to detect when 10705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // candidate selection starts or stops, due to success or failure. 10715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (transport->all_channels_writable()) { 10725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (ice_connection_state_ == 10735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PeerConnectionInterface::kIceConnectionChecking || 10745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_connection_state_ == 10755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PeerConnectionInterface::kIceConnectionDisconnected) { 10765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetIceConnectionState(PeerConnectionInterface::kIceConnectionConnected); 10775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 10785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else if (transport->HasChannels()) { 10795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If the current state is Connected or Completed, then there were writable 10805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // channels but now there are not, so the next state must be Disconnected. 10815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (ice_connection_state_ == 10825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PeerConnectionInterface::kIceConnectionConnected || 10835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_connection_state_ == 10845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PeerConnectionInterface::kIceConnectionCompleted) { 10855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetIceConnectionState( 10865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PeerConnectionInterface::kIceConnectionDisconnected); 10875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 10885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 10895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 10905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 10915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::OnTransportProxyCandidatesReady( 10925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::TransportProxy* proxy, const cricket::Candidates& candidates) { 10935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 10945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ProcessNewLocalCandidate(proxy->content_name(), candidates); 10955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 10965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 10975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::ExpectSetLocalDescription(Action action) { 10985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ((action == kOffer && state() == STATE_INIT) || 10995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // update local offer 11005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kOffer && state() == STATE_SENTINITIATE) || 11015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // update the current ongoing session. 11025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kOffer && state() == STATE_RECEIVEDACCEPT) || 11035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kOffer && state() == STATE_SENTACCEPT) || 11045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kOffer && state() == STATE_INPROGRESS) || 11055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // accept remote offer 11065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kAnswer && state() == STATE_RECEIVEDINITIATE) || 11075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kAnswer && state() == STATE_SENTPRACCEPT) || 11085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kPrAnswer && state() == STATE_RECEIVEDINITIATE) || 11095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kPrAnswer && state() == STATE_SENTPRACCEPT)); 11105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 11115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::ExpectSetRemoteDescription(Action action) { 11135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ((action == kOffer && state() == STATE_INIT) || 11145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // update remote offer 11155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kOffer && state() == STATE_RECEIVEDINITIATE) || 11165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // update the current ongoing session 11175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kOffer && state() == STATE_RECEIVEDACCEPT) || 11185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kOffer && state() == STATE_SENTACCEPT) || 11195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kOffer && state() == STATE_INPROGRESS) || 11205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // accept local offer 11215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kAnswer && state() == STATE_SENTINITIATE) || 11225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kAnswer && state() == STATE_RECEIVEDPRACCEPT) || 11235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kPrAnswer && state() == STATE_SENTINITIATE) || 11245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org (action == kPrAnswer && state() == STATE_RECEIVEDPRACCEPT)); 11255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 11265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::OnCandidatesAllocationDone() { 11285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(signaling_thread()->IsCurrent()); 11295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (ice_observer_) { 11305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_observer_->OnIceGatheringChange( 11315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PeerConnectionInterface::kIceGatheringComplete); 11325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_observer_->OnIceComplete(); 11335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 11345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 11355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Enabling voice and video channel. 11375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::EnableChannels() { 11385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (voice_channel_ && !voice_channel_->enabled()) 11395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org voice_channel_->Enable(true); 11405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (video_channel_ && !video_channel_->enabled()) 11425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org video_channel_->Enable(true); 11435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (data_channel_.get() && !data_channel_->enabled()) 11455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org data_channel_->Enable(true); 11465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 11475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::ProcessNewLocalCandidate( 11495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string& content_name, 11505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::Candidates& candidates) { 11515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int sdp_mline_index; 11525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!GetLocalCandidateMediaIndex(content_name, &sdp_mline_index)) { 11535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "ProcessNewLocalCandidate: content name " 11545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << content_name << " not found"; 11555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 11565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 11575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (cricket::Candidates::const_iterator citer = candidates.begin(); 11595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org citer != candidates.end(); ++citer) { 11605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Use content_name as the candidate media id. 11615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org JsepIceCandidate candidate(content_name, sdp_mline_index, *citer); 11625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (ice_observer_) { 11635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_observer_->OnIceCandidate(&candidate); 11645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 11655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (local_desc_) { 11665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org local_desc_->AddCandidate(&candidate); 11675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 11685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 11695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 11705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org// Returns the media index for a local ice candidate given the content name. 11725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::GetLocalCandidateMediaIndex(const std::string& content_name, 11735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org int* sdp_mline_index) { 11745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!BaseSession::local_description() || !sdp_mline_index) 11755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 11765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool content_found = false; 11785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const ContentInfos& contents = BaseSession::local_description()->contents(); 11795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t index = 0; index < contents.size(); ++index) { 11805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (contents[index].name == content_name) { 1181b30f5947ff2af0e3b77751bacec5dc7350c4dcd6sergeyu@chromium.org *sdp_mline_index = static_cast<int>(index); 11825976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org content_found = true; 11835976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 11845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 11855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 11865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return content_found; 11875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 11885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 11895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::UseCandidatesInSessionDescription( 11905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const SessionDescriptionInterface* remote_desc) { 11915976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!remote_desc) 11925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 11935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool ret = true; 11945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t m = 0; m < remote_desc->number_of_mediasections(); ++m) { 11955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const IceCandidateCollection* candidates = remote_desc->candidates(m); 11965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t n = 0; n < candidates->count(); ++n) { 11975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ret = UseCandidate(candidates->at(n)); 11985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!ret) 11995976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org break; 12005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return ret; 12035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 12045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 12055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::UseCandidate( 12065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const IceCandidateInterface* candidate) { 12075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 12085976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t mediacontent_index = static_cast<size_t>(candidate->sdp_mline_index()); 12095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org size_t remote_content_size = 12105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org BaseSession::remote_description()->contents().size(); 12115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (mediacontent_index >= remote_content_size) { 12125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) 12135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org << "UseRemoteCandidateInSession: Invalid candidate media index."; 12145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 12155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 12175976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::ContentInfo content = 12185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org BaseSession::remote_description()->contents()[mediacontent_index]; 12195976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::vector<cricket::Candidate> candidates; 12205976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org candidates.push_back(candidate->candidate()); 12215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Invoking BaseSession method to handle remote candidates. 12225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org std::string error; 12235976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (OnRemoteCandidates(content.name, candidates, &error)) { 12245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Candidates successfully submitted for checking. 12255976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (ice_connection_state_ == PeerConnectionInterface::kIceConnectionNew || 12265976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ice_connection_state_ == 12275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org PeerConnectionInterface::kIceConnectionDisconnected) { 12285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If state is New, then the session has just gotten its first remote ICE 12295976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // candidates, so go to Checking. 12305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If state is Disconnected, the session is re-using old candidates or 12315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // receiving additional ones, so go to Checking. 12325976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // If state is Connected, stay Connected. 12335976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO(bemasc): If state is Connected, and the new candidates are for a 12345976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // newly added transport, then the state actually _should_ move to 12355976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // checking. Add a way to distinguish that case. 12365976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SetIceConnectionState(PeerConnectionInterface::kIceConnectionChecking); 12375976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12385976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // TODO(bemasc): If state is Completed, go back to Connected. 12395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } else { 12405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_WARNING) << error; 12415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 12435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 12445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 12455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::RemoveUnusedChannelsAndTransports( 12465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const SessionDescription* desc) { 12475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::ContentInfo* voice_info = 12485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::GetFirstAudioContent(desc); 12495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if ((!voice_info || voice_info->rejected) && voice_channel_) { 12505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org mediastream_signaling_->OnAudioChannelClose(); 12515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalVoiceChannelDestroyed(); 12525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string content_name = voice_channel_->content_name(); 12535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org channel_manager_->DestroyVoiceChannel(voice_channel_.release()); 12545976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org DestroyTransportProxy(content_name); 12555976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12565976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 12575976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::ContentInfo* video_info = 12585976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::GetFirstVideoContent(desc); 12595976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if ((!video_info || video_info->rejected) && video_channel_) { 12605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org mediastream_signaling_->OnVideoChannelClose(); 12615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalVideoChannelDestroyed(); 12625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string content_name = video_channel_->content_name(); 12635976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org channel_manager_->DestroyVideoChannel(video_channel_.release()); 12645976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org DestroyTransportProxy(content_name); 12655976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12665976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 12675976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::ContentInfo* data_info = 12685976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org cricket::GetFirstDataContent(desc); 12695976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if ((!data_info || data_info->rejected) && data_channel_) { 12705976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org mediastream_signaling_->OnDataChannelClose(); 12715976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SignalDataChannelDestroyed(); 12725976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const std::string content_name = data_channel_->content_name(); 12735976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org channel_manager_->DestroyDataChannel(data_channel_.release()); 12745976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org DestroyTransportProxy(content_name); 12755976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12765976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 12775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1278c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org// TODO(mallinath) - Add a correct error code if the channels are not creatued 1279c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org// due to BUNDLE is enabled but rtcp-mux is disabled. 12805976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgbool WebRtcSession::CreateChannels(const SessionDescription* desc) { 12815976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Disabling the BUNDLE flag in PortAllocator if offer disabled it. 1282c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE); 1283c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (state() == STATE_INIT && !bundle_enabled) { 12845976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org port_allocator()->set_flags(port_allocator()->flags() & 12855976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ~cricket::PORTALLOCATOR_ENABLE_BUNDLE); 12865976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12875976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 12885976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org // Creating the media channels and transport proxies. 12895976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::ContentInfo* voice = cricket::GetFirstAudioContent(desc); 12905976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (voice && !voice->rejected && !voice_channel_) { 1291c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (!CreateVoiceChannel(voice)) { 12925976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "Failed to create voice channel."; 12935976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 12945976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12955976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 12965976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 12975976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::ContentInfo* video = cricket::GetFirstVideoContent(desc); 12985976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (video && !video->rejected && !video_channel_) { 1299c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (!CreateVideoChannel(video)) { 13005976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "Failed to create video channel."; 13015976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 13025976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 13035976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 13045976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 13055976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org const cricket::ContentInfo* data = cricket::GetFirstDataContent(desc); 13065976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (data_channel_type_ != cricket::DCT_NONE && 13075976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org data && !data->rejected && !data_channel_.get()) { 1308c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (!CreateDataChannel(data)) { 13095976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org LOG(LS_ERROR) << "Failed to create data channel."; 13105976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return false; 13115976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 13125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 13135976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 13145976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return true; 13155976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 13165976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1317c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.orgbool WebRtcSession::CreateVoiceChannel(const cricket::ContentInfo* content) { 13185976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org voice_channel_.reset(channel_manager_->CreateVoiceChannel( 1319c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org this, content->name, true)); 1320c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return (voice_channel_ != NULL); 13215976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 13225976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1323c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.orgbool WebRtcSession::CreateVideoChannel(const cricket::ContentInfo* content) { 13245976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org video_channel_.reset(channel_manager_->CreateVideoChannel( 1325c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org this, content->name, true, voice_channel_.get())); 1326c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return (video_channel_ != NULL); 13275976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 13285976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1329c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.orgbool WebRtcSession::CreateDataChannel(const cricket::ContentInfo* content) { 13305976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org bool rtcp = (data_channel_type_ == cricket::DCT_RTP); 13315976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org data_channel_.reset(channel_manager_->CreateDataChannel( 1332e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org this, content->name, rtcp, data_channel_type_)); 1333e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (!data_channel_.get()) { 1334e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return false; 1335e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 1336e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org data_channel_->SignalDataReceived.connect( 1337e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org this, &WebRtcSession::OnDataReceived); 1338e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return true; 13395976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 13405976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 13415976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.orgvoid WebRtcSession::CopySavedCandidates( 13425976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org SessionDescriptionInterface* dest_desc) { 13435976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org if (!dest_desc) { 13445976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org ASSERT(false); 13455976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 13465976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 13475976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org for (size_t i = 0; i < saved_candidates_.size(); ++i) { 13485976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org dest_desc->AddCandidate(saved_candidates_[i]); 13495976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org delete saved_candidates_[i]; 13505976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 13515976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org saved_candidates_.clear(); 13525976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 13535976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1354e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org// Look for OPEN messages and set up data channels in response. 1355e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.orgvoid WebRtcSession::OnDataReceived( 1356e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org cricket::DataChannel* channel, 1357e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org const cricket::ReceiveDataParams& params, 1358e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org const talk_base::Buffer& payload) { 1359e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (params.type != cricket::DMT_CONTROL) { 13605976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org return; 13615976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 13625976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1363e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org std::string label; 1364e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org DataChannelInit config; 1365e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (!mediastream_signaling_->ParseDataChannelOpenMessage( 1366e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org payload, &label, &config)) { 1367e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org LOG(LS_WARNING) << "Failed to parse data channel OPEN message."; 1368e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return; 1369e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org } 1370e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 1371e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org config.negotiated = true; // This is the negotiation. 1372e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org 1373e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org if (!mediastream_signaling_->AddDataChannelFromOpenMessage( 1374e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org label, config)) { 1375e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org LOG(LS_WARNING) << "Failed to create data channel from OPEN message."; 1376e6781b6279d20210a5050a3e55e9c7effd3b144ewu@webrtc.org return; 13775976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org } 13785976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} 13795976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org 1380c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org// Returns false if bundle is enabled and rtcp_mux is disabled. 1381c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.orgbool WebRtcSession::VerifyBundleSettings(const SessionDescription* desc) { 1382c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org bool bundle_enabled = desc->HasGroup(cricket::GROUP_TYPE_BUNDLE); 1383c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (!bundle_enabled) 1384c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return true; 1385c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org 1386c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org const cricket::ContentGroup* bundle_group = 1387c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org desc->GetGroupByName(cricket::GROUP_TYPE_BUNDLE); 1388c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org ASSERT(bundle_group != NULL); 1389c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org 1390c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org const cricket::ContentInfos& contents = desc->contents(); 1391c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org for (cricket::ContentInfos::const_iterator citer = contents.begin(); 1392c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org citer != contents.end(); ++citer) { 1393c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org const cricket::ContentInfo* content = (&*citer); 1394c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org ASSERT(content != NULL); 1395c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (bundle_group->HasContentName(content->name) && 1396c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org !content->rejected && content->type == cricket::NS_JINGLE_RTP) { 1397c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org if (!HasRtcpMuxEnabled(content)) 1398c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return false; 1399c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org } 1400c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org } 1401c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org // RTCP-MUX is enabled in all the contents. 1402c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return true; 1403c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org} 1404c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org 1405c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.orgbool WebRtcSession::HasRtcpMuxEnabled( 1406c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org const cricket::ContentInfo* content) { 1407c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org const cricket::MediaContentDescription* description = 1408c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org static_cast<cricket::MediaContentDescription*>(content->description); 1409c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org return description->rtcp_mux(); 1410c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org} 1411c1c67e5a722135af4ca83ee4c7d2dbe3f26bae70henrike@webrtc.org 14125976650443d68ccfadf1dea24999ee459dd2819mflodman@webrtc.org} // namespace webrtc 1413