10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/*
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2004--2005, Google Inc.
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met:
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  1. Redistributions of source code must retain the above copyright notice,
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer.
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  2. Redistributions in binary form must reproduce the above copyright notice,
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     this list of conditions and the following disclaimer in the documentation
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     and/or other materials provided with the distribution.
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *  3. The name of the author may not be used to endorse or promote products
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *     derived from this software without specific prior written permission.
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/session.h"
295528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org
300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/dtlstransport.h"
310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/p2ptransport.h"
320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/sessionclient.h"
330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/transport.h"
340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/transportchannelproxy.h"
350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/transportinfo.h"
36cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/xmpp/constants.h"
37cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "talk/xmpp/jid.h"
38cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/bind.h"
39cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/common.h"
40cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/helpers.h"
41cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/logging.h"
42cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/scoped_ptr.h"
43cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org#include "webrtc/base/sslstreamadapter.h"
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/p2p/base/constants.h"
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace cricket {
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
492a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgusing rtc::Bind;
505528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BadMessage(const buzz::QName type,
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                const std::string& text,
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                MessageError* err) {
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  err->SetType(type);
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  err->SetText(text);
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return false;
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportProxy::~TransportProxy() {
600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (ChannelMap::iterator iter = channels_.begin();
610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != channels_.end(); ++iter) {
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    iter->second->SignalDestroyed(iter->second);
630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    delete iter->second;
640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6732a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.orgconst std::string& TransportProxy::type() const {
680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return transport_->get()->type();
690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannel* TransportProxy::GetChannel(int component) {
722a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  ASSERT(rtc::Thread::Current() == worker_thread_);
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return GetChannelProxy(component);
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannel* TransportProxy::CreateChannel(
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string& name, int component) {
782a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  ASSERT(rtc::Thread::Current() == worker_thread_);
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(GetChannel(component) == NULL);
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(!transport_->get()->HasChannel(component));
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // We always create a proxy in case we need to change out the transport later.
830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportChannelProxy* channel =
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      new TransportChannelProxy(content_name(), name, component);
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  channels_[component] = channel;
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If we're already negotiated, create an impl and hook it up to the proxy
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // channel. If we're connecting, create an impl but don't hook it up yet.
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (negotiated_) {
905528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org    SetupChannelProxy_w(component, channel);
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else if (connecting_) {
925528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org    GetOrCreateChannelProxyImpl_w(component);
930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return channel;
950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool TransportProxy::HasChannel(int component) {
980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return transport_->get()->HasChannel(component);
990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid TransportProxy::DestroyChannel(int component) {
1022a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  ASSERT(rtc::Thread::Current() == worker_thread_);
1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportChannel* channel = GetChannel(component);
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (channel) {
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // If the state of TransportProxy is not NEGOTIATED
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // then TransportChannelProxy and its impl are not
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // connected. Both must be connected before
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // deletion.
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!negotiated_) {
1105528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      SetupChannelProxy_w(component, GetChannelProxy(component));
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    channels_.erase(component);
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    channel->SignalDestroyed(channel);
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    delete channel;
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid TransportProxy::ConnectChannels() {
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!connecting_) {
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!negotiated_) {
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      for (ChannelMap::iterator iter = channels_.begin();
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org           iter != channels_.end(); ++iter) {
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        GetOrCreateChannelProxyImpl(iter->first);
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    connecting_ = true;
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(juberti): Right now Transport::ConnectChannels doesn't work if we
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // don't have any channels yet, so we need to allow this method to be called
1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // multiple times. Once we fix Transport, we can move this call inside the
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // if (!connecting_) block.
1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport_->get()->ConnectChannels();
1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid TransportProxy::CompleteNegotiation() {
1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!negotiated_) {
1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    for (ChannelMap::iterator iter = channels_.begin();
1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org         iter != channels_.end(); ++iter) {
1405528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      SetupChannelProxy(iter->first, iter->second);
1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    negotiated_ = true;
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid TransportProxy::AddSentCandidates(const Candidates& candidates) {
1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (Candidates::const_iterator cand = candidates.begin();
1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       cand != candidates.end(); ++cand) {
1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    sent_candidates_.push_back(*cand);
1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid TransportProxy::AddUnsentCandidates(const Candidates& candidates) {
1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (Candidates::const_iterator cand = candidates.begin();
1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       cand != candidates.end(); ++cand) {
1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    unsent_candidates_.push_back(*cand);
1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool TransportProxy::GetChannelNameFromComponent(
1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int component, std::string* channel_name) const {
1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const TransportChannelProxy* channel = GetChannelProxy(component);
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (channel == NULL) {
1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  *channel_name = channel->name();
1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool TransportProxy::GetComponentFromChannelName(
1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string& channel_name, int* component) const {
1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const TransportChannelProxy* channel = GetChannelProxyByName(channel_name);
1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (channel == NULL) {
1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  *component = channel->component();
1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannelProxy* TransportProxy::GetChannelProxy(int component) const {
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ChannelMap::const_iterator iter = channels_.find(component);
1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return (iter != channels_.end()) ? iter->second : NULL;
1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannelProxy* TransportProxy::GetChannelProxyByName(
1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string& name) const {
1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (ChannelMap::const_iterator iter = channels_.begin();
1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != channels_.end();
1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       ++iter) {
1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (iter->second->name() == name) {
1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return iter->second;
1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return NULL;
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannelImpl* TransportProxy::GetOrCreateChannelProxyImpl(
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int component) {
2015528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org  return worker_thread_->Invoke<TransportChannelImpl*>(Bind(
2025528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      &TransportProxy::GetOrCreateChannelProxyImpl_w, this, component));
2035528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org}
2045528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org
2055528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.orgTransportChannelImpl* TransportProxy::GetOrCreateChannelProxyImpl_w(
2065528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org    int component) {
2072a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  ASSERT(rtc::Thread::Current() == worker_thread_);
2080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportChannelImpl* impl = transport_->get()->GetChannel(component);
2090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (impl == NULL) {
2100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    impl = transport_->get()->CreateChannel(component);
2110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return impl;
2130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2155528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.orgvoid TransportProxy::SetupChannelProxy(
2165528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org    int component, TransportChannelProxy* transproxy) {
2175528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org  worker_thread_->Invoke<void>(Bind(
2185528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      &TransportProxy::SetupChannelProxy_w, this, component, transproxy));
2195528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org}
2205528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org
2215528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.orgvoid TransportProxy::SetupChannelProxy_w(
2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    int component, TransportChannelProxy* transproxy) {
2232a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  ASSERT(rtc::Thread::Current() == worker_thread_);
2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportChannelImpl* impl = GetOrCreateChannelProxyImpl(component);
2250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(impl != NULL);
2260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transproxy->SetImplementation(impl);
2270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2295528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.orgvoid TransportProxy::ReplaceChannelProxyImpl(TransportChannelProxy* proxy,
2305528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org                                             TransportChannelImpl* impl) {
2315528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org  worker_thread_->Invoke<void>(Bind(
2325528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      &TransportProxy::ReplaceChannelProxyImpl_w, this, proxy, impl));
2335528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org}
2345528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org
2355528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.orgvoid TransportProxy::ReplaceChannelProxyImpl_w(TransportChannelProxy* proxy,
2365528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org                                               TransportChannelImpl* impl) {
2372a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  ASSERT(rtc::Thread::Current() == worker_thread_);
2385528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org  ASSERT(proxy != NULL);
2395528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org  proxy->SetImplementation(impl);
2405528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org}
2415528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org
2420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// This function muxes |this| onto |target| by repointing |this| at
2430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// |target|'s transport and setting our TransportChannelProxies
2440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// to point to |target|'s underlying implementations.
2450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool TransportProxy::SetupMux(TransportProxy* target) {
2460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Bail out if there's nothing to do.
2470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (transport_ == target->transport_) {
2480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return true;
2490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Run through all channels and remove any non-rtp transport channels before
2520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // setting target transport channels.
2530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (ChannelMap::const_iterator iter = channels_.begin();
2540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != channels_.end(); ++iter) {
2550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!target->transport_->get()->HasChannel(iter->first)) {
2560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Remove if channel doesn't exist in |transport_|.
2575528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      ReplaceChannelProxyImpl(iter->second, NULL);
2580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else {
2590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Replace the impl for all the TransportProxyChannels with the channels
2600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // from |target|'s transport. Fail if there's not an exact match.
2615528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org      ReplaceChannelProxyImpl(
2625528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org          iter->second, target->transport_->get()->CreateChannel(iter->first));
2630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
2640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
2650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Now replace our transport. Must happen afterwards because
2670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // it deletes all impls as a side effect.
2680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport_ = target->transport_;
2690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport_->get()->SignalCandidatesReady.connect(
2700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      this, &TransportProxy::OnTransportCandidatesReady);
2710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_candidates_allocated(target->candidates_allocated());
2720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
2730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
275e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.orgvoid TransportProxy::SetIceRole(IceRole role) {
276e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  transport_->get()->SetIceRole(role);
2770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool TransportProxy::SetLocalTransportDescription(
280f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    const TransportDescription& description,
281f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    ContentAction action,
282f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    std::string* error_desc) {
2830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If this is an answer, finalize the negotiation.
2840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (action == CA_ANSWER) {
2850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    CompleteNegotiation();
2860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
287f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org  bool result = transport_->get()->SetLocalTransportDescription(description,
288f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org                                                                action,
289f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org                                                                error_desc);
290f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org  if (result)
291f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org    local_description_set_ = true;
292f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org  return result;
2930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
2940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
2950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool TransportProxy::SetRemoteTransportDescription(
296f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    const TransportDescription& description,
297f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    ContentAction action,
298f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    std::string* error_desc) {
2990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If this is an answer, finalize the negotiation.
3000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (action == CA_ANSWER) {
3010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    CompleteNegotiation();
3020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
303f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org  bool result = transport_->get()->SetRemoteTransportDescription(description,
304f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org                                                                 action,
305f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org                                                                 error_desc);
306f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org  if (result)
307f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org    remote_description_set_ = true;
308f72f5a64fe04356b56ddfb84c6ed488d61ced7c4buildbot@webrtc.org  return result;
3090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid TransportProxy::OnSignalingReady() {
3120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If we're starting a new allocation sequence, reset our state.
3130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_candidates_allocated(false);
3140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport_->get()->OnSignalingReady();
3150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool TransportProxy::OnRemoteCandidates(const Candidates& candidates,
3180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                        std::string* error) {
3190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Ensure the transport is negotiated before handling candidates.
3200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(juberti): Remove this once everybody calls SetLocalTD.
3210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CompleteNegotiation();
3220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Verify each candidate before passing down to transport layer.
3240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (Candidates::const_iterator cand = candidates.begin();
3250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       cand != candidates.end(); ++cand) {
3260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!transport_->get()->VerifyCandidate(*cand, error))
3270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
3280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!HasChannel(cand->component())) {
3290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *error = "Candidate has unknown component: " + cand->ToString() +
3300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org               " for content: " + content_name_;
3310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
3320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
3330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport_->get()->OnRemoteCandidates(candidates);
3350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
3360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3385aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.orgvoid TransportProxy::SetIdentity(
3392a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org    rtc::SSLIdentity* identity) {
3405aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  transport_->get()->SetIdentity(identity);
3415aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org}
3425aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
3430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstd::string BaseSession::StateToString(State state) {
3440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (state) {
3450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_INIT:
3460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_INIT";
3470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_SENTINITIATE:
3480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_SENTINITIATE";
3490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_RECEIVEDINITIATE:
3500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_RECEIVEDINITIATE";
3510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_SENTPRACCEPT:
3520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_SENTPRACCEPT";
3530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_SENTACCEPT:
3540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_SENTACCEPT";
3550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_RECEIVEDPRACCEPT:
3560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_RECEIVEDPRACCEPT";
3570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_RECEIVEDACCEPT:
3580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_RECEIVEDACCEPT";
3590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_SENTMODIFY:
3600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_SENTMODIFY";
3610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_RECEIVEDMODIFY:
3620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_RECEIVEDMODIFY";
3630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_SENTREJECT:
3640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_SENTREJECT";
3650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_RECEIVEDREJECT:
3660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_RECEIVEDREJECT";
3670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_SENTREDIRECT:
3680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_SENTREDIRECT";
3690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_SENTTERMINATE:
3700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_SENTTERMINATE";
3710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_RECEIVEDTERMINATE:
3720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_RECEIVEDTERMINATE";
3730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_INPROGRESS:
3740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_INPROGRESS";
3750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case Session::STATE_DEINIT:
3760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return "STATE_DEINIT";
3770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
3780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
3790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
3802a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  return "STATE_" + rtc::ToString(state);
3810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
3820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
3832a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgBaseSession::BaseSession(rtc::Thread* signaling_thread,
3842a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org                         rtc::Thread* worker_thread,
3850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                         PortAllocator* port_allocator,
3860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                         const std::string& sid,
3870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                         const std::string& content_type,
3880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                         bool initiator)
3890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    : state_(STATE_INIT),
3900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      error_(ERROR_NONE),
3910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      signaling_thread_(signaling_thread),
3920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      worker_thread_(worker_thread),
3930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      port_allocator_(port_allocator),
3940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      sid_(sid),
3950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      content_type_(content_type),
3960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      transport_type_(NS_GINGLE_P2P),
3970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      initiator_(initiator),
3980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      identity_(NULL),
3992a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org      ice_tiebreaker_(rtc::CreateRandomId64()),
4000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      role_switch_(false) {
4010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread->IsCurrent());
4020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgBaseSession::~BaseSession() {
4050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
4060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(state_ != STATE_DEINIT);
4080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LogState(state_, STATE_DEINIT);
4090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  state_ = STATE_DEINIT;
4100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalState(this, state_);
4110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
4130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
4140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    delete iter->second;
4150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
41632a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org}
41732a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org
41832a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.orgconst SessionDescription* BaseSession::local_description() const {
41932a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // TODO(tommi): Assert on thread correctness.
42032a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  return local_description_.get();
42132a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org}
42232a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org
42332a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.orgconst SessionDescription* BaseSession::remote_description() const {
42432a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // TODO(tommi): Assert on thread correctness.
42532a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  return remote_description_.get();
42632a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org}
42732a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org
42832a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.orgSessionDescription* BaseSession::remote_description() {
42932a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // TODO(tommi): Assert on thread correctness.
43032a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  return remote_description_.get();
43132a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org}
43232a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org
43332a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.orgvoid BaseSession::set_local_description(const SessionDescription* sdesc) {
43432a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // TODO(tommi): Assert on thread correctness.
43532a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  if (sdesc != local_description_.get())
43632a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org    local_description_.reset(sdesc);
43732a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org}
4380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
43932a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.orgvoid BaseSession::set_remote_description(SessionDescription* sdesc) {
44032a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // TODO(tommi): Assert on thread correctness.
44132a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  if (sdesc != remote_description_)
44232a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org    remote_description_.reset(sdesc);
44332a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org}
44432a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org
44532a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.orgconst SessionDescription* BaseSession::initiator_description() const {
44632a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // TODO(tommi): Assert on thread correctness.
44732a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  return initiator_ ? local_description_.get() : remote_description_.get();
4480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4502a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgbool BaseSession::SetIdentity(rtc::SSLIdentity* identity) {
4515aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  if (identity_)
4525aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    return false;
4535aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  identity_ = identity;
4545aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
4555aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org       iter != transports_.end(); ++iter) {
4565aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org    iter->second->SetIdentity(identity_);
4575aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  }
4585aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org  return true;
4595aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org}
4605aed3bb9fb287faecd773b88bb68732c31579590wu@webrtc.org
4610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::PushdownTransportDescription(ContentSource source,
462f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                                               ContentAction action,
463f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                                               std::string* error_desc) {
4640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (source == CS_LOCAL) {
46532a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org    return PushdownLocalTransportDescription(local_description(),
466f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                                             action,
467f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                                             error_desc);
4680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
46932a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  return PushdownRemoteTransportDescription(remote_description(),
470f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                                            action,
471f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                                            error_desc);
4720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::PushdownLocalTransportDescription(
4750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const SessionDescription* sdesc,
476f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    ContentAction action,
477f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    std::string* error_desc) {
4780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Update the Transports with the right information, and trigger them to
4790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // start connecting.
4800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
4810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
4820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // If no transport info was in this session description, ret == false
4830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // and we just skip this one.
4840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    TransportDescription tdesc;
4850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool ret = GetTransportDescription(
4860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        sdesc, iter->second->content_name(), &tdesc);
4870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (ret) {
488f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      if (!iter->second->SetLocalTransportDescription(tdesc, action,
489f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                                                      error_desc)) {
4900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return false;
4910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
4920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      iter->second->ConnectChannels();
4940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
4950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
4960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
4970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
4980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
4990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::PushdownRemoteTransportDescription(
5010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const SessionDescription* sdesc,
502f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    ContentAction action,
503f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    std::string* error_desc) {
5040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Update the Transports with the right information.
5050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
5060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
5070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    TransportDescription tdesc;
5080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // If no transport info was in this session description, ret == false
5100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // and we just skip this one.
5110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    bool ret = GetTransportDescription(
5120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        sdesc, iter->second->content_name(), &tdesc);
5130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (ret) {
514f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      if (!iter->second->SetRemoteTransportDescription(tdesc, action,
515f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org                                                       error_desc)) {
5160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return false;
5170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
5180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
5190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
5200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
5220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannel* BaseSession::CreateChannel(const std::string& content_name,
5250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                             const std::string& channel_name,
5260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                             int component) {
5270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // We create the proxy "on demand" here because we need to support
5280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // creating channels at any time, even before we send or receive
5290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // initiate messages, which is before we create the transports.
5300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportProxy* transproxy = GetOrCreateTransportProxy(content_name);
5310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return transproxy->CreateChannel(channel_name, component);
5320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportChannel* BaseSession::GetChannel(const std::string& content_name,
5350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                          int component) {
5360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportProxy* transproxy = GetTransportProxy(content_name);
5370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (transproxy == NULL)
5380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return NULL;
53932a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org
54032a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  return transproxy->GetChannel(component);
5410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::DestroyChannel(const std::string& content_name,
5440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 int component) {
5450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportProxy* transproxy = GetTransportProxy(content_name);
5460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(transproxy != NULL);
5470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transproxy->DestroyChannel(component);
5480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportProxy* BaseSession::GetOrCreateTransportProxy(
5510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string& content_name) {
5520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportProxy* transproxy = GetTransportProxy(content_name);
5530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (transproxy)
5540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return transproxy;
5550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  Transport* transport = CreateTransport(content_name);
557e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  transport->SetIceRole(initiator_ ? ICEROLE_CONTROLLING : ICEROLE_CONTROLLED);
558e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org  transport->SetIceTiebreaker(ice_tiebreaker_);
5590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO: Connect all the Transport signals to TransportProxy
5600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // then to the BaseSession.
5610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport->SignalConnecting.connect(
5620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      this, &BaseSession::OnTransportConnecting);
5630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport->SignalWritableState.connect(
5640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      this, &BaseSession::OnTransportWritable);
5650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport->SignalRequestSignaling.connect(
5660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      this, &BaseSession::OnTransportRequestSignaling);
5670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport->SignalTransportError.connect(
5680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      this, &BaseSession::OnTransportSendError);
5690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport->SignalRouteChange.connect(
5700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      this, &BaseSession::OnTransportRouteChange);
5710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport->SignalCandidatesAllocationDone.connect(
5720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      this, &BaseSession::OnTransportCandidatesAllocationDone);
5730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport->SignalRoleConflict.connect(
5740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      this, &BaseSession::OnRoleConflict);
575f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org  transport->SignalCompleted.connect(
576f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org      this, &BaseSession::OnTransportCompleted);
577f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org  transport->SignalFailed.connect(
578f5e5b3a9ce372d0e3cc594bf0036dda64a57d81dmallinath@webrtc.org      this, &BaseSession::OnTransportFailed);
5790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5805528070a0c76057a000b877fc56ca4180ad2087bmallinath@webrtc.org  transproxy = new TransportProxy(worker_thread_, sid_, content_name,
5810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                  new TransportWrapper(transport));
5820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transproxy->SignalCandidatesReady.connect(
5830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      this, &BaseSession::OnTransportProxyCandidatesReady);
5840cba5aa9261d60676bc472ebb6b60620f453a76ehenrike@webrtc.org  if (identity_)
5850cba5aa9261d60676bc472ebb6b60620f453a76ehenrike@webrtc.org    transproxy->SetIdentity(identity_);
5860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transports_[content_name] = transproxy;
5870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return transproxy;
5890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransport* BaseSession::GetTransport(const std::string& content_name) {
5920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportProxy* transproxy = GetTransportProxy(content_name);
5930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (transproxy == NULL)
5940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return NULL;
5950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return transproxy->impl();
5960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
5970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
5980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportProxy* BaseSession::GetTransportProxy(
5990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string& content_name) {
6000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportMap::iterator iter = transports_.find(content_name);
6010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return (iter != transports_.end()) ? iter->second : NULL;
6020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportProxy* BaseSession::GetTransportProxy(const Transport* transport) {
6050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
6060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
6070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    TransportProxy* transproxy = iter->second;
6080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (transproxy->impl() == transport) {
6090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return transproxy;
6100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
6110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return NULL;
6130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportProxy* BaseSession::GetFirstTransportProxy() {
6160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (transports_.empty())
6170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return NULL;
6180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return transports_.begin()->second;
6190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::DestroyTransportProxy(
6220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string& content_name) {
6230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportMap::iterator iter = transports_.find(content_name);
6240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (iter != transports_.end()) {
6250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    delete iter->second;
6260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    transports_.erase(content_name);
6270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgcricket::Transport* BaseSession::CreateTransport(
6310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string& content_name) {
6320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(transport_type_ == NS_GINGLE_P2P);
6330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return new cricket::DtlsTransport<P2PTransport>(
6340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      signaling_thread(), worker_thread(), content_name,
6350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      port_allocator(), identity_);
6360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::GetStats(SessionStats* stats) {
6390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
6400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
6410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::string proxy_id = iter->second->content_name();
6420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // We are ignoring not-yet-instantiated transports.
6430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (iter->second->impl()) {
6440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      std::string transport_id = iter->second->impl()->content_name();
6450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      stats->proxy_to_transport[proxy_id] = transport_id;
6460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (stats->transport_stats.find(transport_id)
6470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          == stats->transport_stats.end()) {
6480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        TransportStats subinfos;
6490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        if (!iter->second->impl()->GetStats(&subinfos)) {
6500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          return false;
6510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        }
6520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        stats->transport_stats[transport_id] = subinfos;
6530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
6540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
6550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
6570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::SetState(State state) {
6600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread_->IsCurrent());
6610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (state != state_) {
6620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LogState(state_, state);
6630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    state_ = state;
6640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalState(this, state_);
6650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    signaling_thread_->Post(this, MSG_STATE);
6660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalNewDescription();
6680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
670f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgvoid BaseSession::SetError(Error error, const std::string& error_desc) {
6710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread_->IsCurrent());
6720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (error != error_) {
6730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    error_ = error;
674f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    error_desc_ = error_desc;
6750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalError(this, error);
6760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::OnSignalingReady() {
6800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
6810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
6820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
6830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    iter->second->OnSignalingReady();
6840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// TODO(juberti): Since PushdownLocalTD now triggers the connection process to
6880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org// start, remove this method once everyone calls PushdownLocalTD.
6890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::SpeculativelyConnectAllTransportChannels() {
6900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Put all transports into the connecting state.
6910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
6920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
6930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    iter->second->ConnectChannels();
6940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
6950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
6960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
6970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::OnRemoteCandidates(const std::string& content_name,
6980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                     const Candidates& candidates,
6990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                     std::string* error) {
7000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Give candidates to the appropriate transport, and tell that transport
7010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // to start connecting, if it's not already doing so.
7020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportProxy* transproxy = GetTransportProxy(content_name);
7030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!transproxy) {
7040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    *error = "Unknown content name " + content_name;
7050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
7060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!transproxy->OnRemoteCandidates(candidates, error)) {
7080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
7090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(juberti): Remove this call once we can be sure that we always have
7110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // a local transport description (which will trigger the connection).
7120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transproxy->ConnectChannels();
7130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
7140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
7150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::MaybeEnableMuxingSupport() {
7170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // We need both a local and remote description to decide if we should mux.
7180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if ((state_ == STATE_SENTINITIATE ||
7190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      state_ == STATE_RECEIVEDINITIATE) &&
7200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      ((local_description_ == NULL) ||
7210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      (remote_description_ == NULL))) {
7220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
7230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // In order to perform the multiplexing, we need all proxies to be in the
7260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // negotiated state, i.e. to have implementations underneath.
7270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Ensure that this is the case, regardless of whether we are going to mux.
7280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
7290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
7300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(iter->second->negotiated());
7310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!iter->second->negotiated())
7320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
7330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If both sides agree to BUNDLE, mux all the specified contents onto the
7360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // transport belonging to the first content name in the BUNDLE group.
7370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If the contents are already muxed, this will be a no-op.
7380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(juberti): Should this check that local and remote have configured
7390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // BUNDLE the same way?
7400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool candidates_allocated = IsCandidateAllocationDone();
7410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const ContentGroup* local_bundle_group =
7420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      local_description()->GetGroupByName(GROUP_TYPE_BUNDLE);
7430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const ContentGroup* remote_bundle_group =
7440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      remote_description()->GetGroupByName(GROUP_TYPE_BUNDLE);
7450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (local_bundle_group && remote_bundle_group &&
7460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      local_bundle_group->FirstContentName()) {
7470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const std::string* content_name = local_bundle_group->FirstContentName();
7480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const ContentInfo* content =
7490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        local_description_->GetContentByName(*content_name);
7500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    ASSERT(content != NULL);
7510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!SetSelectedProxy(content->name, local_bundle_group)) {
7520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      LOG(LS_WARNING) << "Failed to set up BUNDLE";
7530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
7540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
7550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // If we weren't done gathering before, we might be done now, as a result
7570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // of enabling mux.
7580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_INFO) << "Enabling BUNDLE, bundling onto transport: "
7590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 << *content_name;
7600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!candidates_allocated) {
7610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      MaybeCandidateAllocationDone();
7620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
7630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
7640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_INFO) << "No BUNDLE information, not bundling.";
7650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
7670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
7680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::SetSelectedProxy(const std::string& content_name,
7700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   const ContentGroup* muxed_group) {
7710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportProxy* selected_proxy = GetTransportProxy(content_name);
7720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!selected_proxy) {
7730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
7740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(selected_proxy->negotiated());
7770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
7780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
7790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // If content is part of the mux group, then repoint its proxy at the
7800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // transport object that we have chosen to mux onto. If the proxy
7810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // is already pointing at the right object, it will be a no-op.
7820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (muxed_group->HasContentName(iter->first) &&
7830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        !iter->second->SetupMux(selected_proxy)) {
7840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
7850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
7860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
7870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
7880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
7890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
7900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::OnTransportCandidatesAllocationDone(Transport* transport) {
7910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(juberti): This is a clunky way of processing the done signal. Instead,
7920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TransportProxy should receive the done signal directly, set its allocated
7930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // flag internally, and then reissue the done signal to Session.
7940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Overall we should make TransportProxy receive *all* the signals from
7950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Transport, since this removes the need to manually iterate over all
7960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // the transports, as is needed to make sure signals are handled properly
7970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // when BUNDLEing.
7987587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org  // TODO(juberti): Per b/7998978, devs and QA are hitting this assert in ways
7997587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org  // that make it prohibitively difficult to run dbg builds. Disabled for now.
8007587c5e0b2fb5100b52bf271370ee1369ba18690henrike@webrtc.org  //ASSERT(!IsCandidateAllocationDone());
8010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
8020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
8030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (iter->second->impl() == transport) {
8040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      iter->second->set_candidates_allocated(true);
8050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
8060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MaybeCandidateAllocationDone();
8080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::IsCandidateAllocationDone() const {
8110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::const_iterator iter = transports_.begin();
8120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
8130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!iter->second->candidates_allocated())
8140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
8150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
8170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::MaybeCandidateAllocationDone() {
8200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (IsCandidateAllocationDone()) {
8210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_INFO) << "Candidate gathering is complete.";
8220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    OnCandidatesAllocationDone();
8230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::OnRoleConflict() {
8270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (role_switch_) {
8280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_WARNING) << "Repeat of role conflict signal from Transport.";
8290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
8300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  role_switch_ = true;
8330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::iterator iter = transports_.begin();
8340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transports_.end(); ++iter) {
8350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Role will be reverse of initial role setting.
836e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org    IceRole role = initiator_ ? ICEROLE_CONTROLLED : ICEROLE_CONTROLLING;
837e560834da4ee5a5f38a96a8cb9290c5ce1096989mallinath@webrtc.org    iter->second->SetIceRole(role);
8380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::LogState(State old_state, State new_state) {
8420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  LOG(LS_INFO) << "Session:" << id()
8430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org               << " Old state:" << StateToString(old_state)
8440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org               << " New state:" << StateToString(new_state)
8450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org               << " Type:" << content_type()
8460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org               << " Transport:" << transport_type();
8470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
84932a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org// static
8500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::GetTransportDescription(const SessionDescription* description,
8510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                          const std::string& content_name,
8520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                          TransportDescription* tdesc) {
8530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!description || !tdesc) {
8540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
8550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const TransportInfo* transport_info =
8570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      description->GetTransportInfoByName(content_name);
8580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!transport_info) {
8590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
8600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  *tdesc = transport_info->description;
8620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
8630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid BaseSession::SignalNewDescription() {
8660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ContentAction action;
8670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ContentSource source;
8680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!GetContentAction(&action, &source)) {
8690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
8700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (source == CS_LOCAL) {
8720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalNewLocalDescription(this, action);
8730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
8740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalNewRemoteDescription(this, action);
8750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
8760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
8770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
8780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BaseSession::GetContentAction(ContentAction* action,
8790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   ContentSource* source) {
8800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (state_) {
8810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // new local description
8820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_SENTINITIATE:
8830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *action = CA_OFFER;
8840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *source = CS_LOCAL;
8850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
8860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_SENTPRACCEPT:
8870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *action = CA_PRANSWER;
8880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *source = CS_LOCAL;
8890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
8900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_SENTACCEPT:
8910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *action = CA_ANSWER;
8920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *source = CS_LOCAL;
8930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
8940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // new remote description
8950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_RECEIVEDINITIATE:
8960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *action = CA_OFFER;
8970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *source = CS_REMOTE;
8980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
8990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_RECEIVEDPRACCEPT:
9000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *action = CA_PRANSWER;
9010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *source = CS_REMOTE;
9020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
9030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_RECEIVEDACCEPT:
9040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *action = CA_ANSWER;
9050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      *source = CS_REMOTE;
9060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
9070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
9080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
9090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
9110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9132a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid BaseSession::OnMessage(rtc::Message *pmsg) {
9140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (pmsg->message_id) {
9150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  case MSG_TIMEOUT:
9160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Session timeout has occured.
917f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    SetError(ERROR_TIME, "Session timeout has occured.");
9180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    break;
9190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  case MSG_STATE:
9210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    switch (state_) {
9220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_SENTACCEPT:
9230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_RECEIVEDACCEPT:
9240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      SetState(STATE_INPROGRESS);
9250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
9260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
9280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Explicitly ignoring some states here.
9290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
9300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
9310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    break;
9320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSession::Session(SessionManager* session_manager,
9360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 const std::string& local_name,
9370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 const std::string& initiator_name,
9380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 const std::string& sid,
9390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 const std::string& content_type,
9400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                 SessionClient* client)
9410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    : BaseSession(session_manager->signaling_thread(),
9420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  session_manager->worker_thread(),
9430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  session_manager->port_allocator(),
9440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  sid, content_type, initiator_name == local_name) {
9450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(client != NULL);
9460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  session_manager_ = session_manager;
9470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  local_name_ = local_name;
9480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  initiator_name_ = initiator_name;
9490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  transport_parser_ = new P2PTransportParser();
9500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  client_ = client;
9510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  initiate_acked_ = false;
9520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  current_protocol_ = PROTOCOL_HYBRID;
9530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgSession::~Session() {
9560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  delete transport_parser_;
9570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
95932a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.orgbool Session::Initiate(const std::string& to,
9600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       const SessionDescription* sdesc) {
9610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
9620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionError error;
9630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Only from STATE_INIT
9650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (state() != STATE_INIT)
9660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
9670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Setup for signaling.
9690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_remote_name(to);
9700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_local_description(sdesc);
9710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!CreateTransportProxies(GetEmptyTransportInfos(sdesc->contents()),
9720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              &error)) {
9730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Could not create transports: " << error.text;
9740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
9750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!SendInitiateMessage(sdesc, &error)) {
9780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Could not send initiate message: " << error.text;
9790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
9800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
9810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // We need to connect transport proxy and impl here so that we can process
9830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // the TransportDescriptions.
9840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SpeculativelyConnectAllTransportChannels();
9850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
986f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  PushdownTransportDescription(CS_LOCAL, CA_OFFER, NULL);
9870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetState(Session::STATE_SENTINITIATE);
9880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
9890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
9900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::Accept(const SessionDescription* sdesc) {
9920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
9930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Only if just received initiate
9950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (state() != STATE_RECEIVEDINITIATE)
9960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
9970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
9980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Setup for signaling.
9990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_local_description(sdesc);
10000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionError error;
10020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!SendAcceptMessage(sdesc, &error)) {
10030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Could not send accept message: " << error.text;
10040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO(juberti): Add BUNDLE support to transport-info messages.
1007f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  PushdownTransportDescription(CS_LOCAL, CA_ANSWER, NULL);
10080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MaybeEnableMuxingSupport();  // Enable transport channel mux if supported.
10090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetState(Session::STATE_SENTACCEPT);
10100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
10110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
10120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::Reject(const std::string& reason) {
10140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
10150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Reject is sent in response to an initiate or modify, to reject the
10170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // request
10180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (state() != STATE_RECEIVEDINITIATE && state() != STATE_RECEIVEDMODIFY)
10190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionError error;
10220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!SendRejectMessage(reason, &error)) {
10230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Could not send reject message: " << error.text;
10240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetState(STATE_SENTREJECT);
10280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
10290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
10300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::TerminateWithReason(const std::string& reason) {
10320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
10330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Either side can terminate, at any time.
10350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (state()) {
10360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_SENTTERMINATE:
10370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_RECEIVEDTERMINATE:
10380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
10390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_SENTREJECT:
10410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_RECEIVEDREJECT:
10420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // We don't need to send terminate if we sent or received a reject...
10430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // it's implicit.
10440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
10450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
10470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      SessionError error;
10480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!SendTerminateMessage(reason, &error)) {
10490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LOG(LS_ERROR) << "Could not send terminate message: " << error.text;
10500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return false;
10510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
10520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
10530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetState(STATE_SENTTERMINATE);
10560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
10570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
10580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10593db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.orgbool Session::SendInfoMessage(const XmlElements& elems,
10603db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.org                              const std::string& remote_name) {
10610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
10620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionError error;
10633db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.org  if (!SendMessage(ACTION_SESSION_INFO, elems, remote_name, &error)) {
10640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Could not send info message " << error.text;
10650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
10680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
10690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendDescriptionInfoMessage(const ContentInfos& contents) {
10710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElements elems;
10720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  WriteError write_error;
10730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!WriteDescriptionInfo(current_protocol_,
10740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            contents,
10750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            GetContentParsers(),
10760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            &elems, &write_error)) {
10770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Could not write description info message: "
10780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  << write_error.text;
10790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionError error;
10820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!SendMessage(ACTION_DESCRIPTION_INFO, elems, &error)) {
10830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Could not send description info message: "
10840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  << error.text;
10850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
10860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
10870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
10880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
10890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
10900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportInfos Session::GetEmptyTransportInfos(
10910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const ContentInfos& contents) const {
10920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportInfos tinfos;
10930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (ContentInfos::const_iterator content = contents.begin();
10940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       content != contents.end(); ++content) {
1095a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org    tinfos.push_back(TransportInfo(content->name,
1096a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                                   TransportDescription(transport_type(),
1097a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                                                        std::string(),
1098a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                                                        std::string())));
10990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return tinfos;
11010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnRemoteCandidates(
11040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    const TransportInfos& tinfos, ParseError* error) {
11050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportInfos::const_iterator tinfo = tinfos.begin();
11060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       tinfo != tinfos.end(); ++tinfo) {
11070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    std::string str_error;
11080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!BaseSession::OnRemoteCandidates(
11090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        tinfo->content_name, tinfo->description.candidates, &str_error)) {
11100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return BadParse(str_error, error);
11110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
11120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
11140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::CreateTransportProxies(const TransportInfos& tinfos,
11170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                     SessionError* error) {
11180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportInfos::const_iterator tinfo = tinfos.begin();
11190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       tinfo != tinfos.end(); ++tinfo) {
11200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (tinfo->description.transport_type != transport_type()) {
11210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      error->SetText("No supported transport in offer.");
11220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
11230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
11240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    GetOrCreateTransportProxy(tinfo->content_name);
11260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
11280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgTransportParserMap Session::GetTransportParsers() {
11310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportParserMap parsers;
11320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  parsers[transport_type()] = transport_parser_;
11330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return parsers;
11340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgCandidateTranslatorMap Session::GetCandidateTranslators() {
11370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  CandidateTranslatorMap translators;
11380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // NOTE: This technique makes it impossible to parse G-ICE
11390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // candidates in session-initiate messages because the channels
11400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // aren't yet created at that point.  Since we don't use candidates
11410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // in session-initiate messages, we should be OK.  Once we switch to
11420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // ICE, this translation shouldn't be necessary.
11430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::const_iterator iter = transport_proxies().begin();
11440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transport_proxies().end(); ++iter) {
11450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    translators[iter->first] = iter->second;
11460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return translators;
11480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgContentParserMap Session::GetContentParsers() {
11510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ContentParserMap parsers;
11520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  parsers[content_type()] = client_;
11530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // We need to be able parse both RTP-based and SCTP-based Jingle
11540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // with the same client.
11550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (content_type() == NS_JINGLE_RTP) {
11560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    parsers[NS_JINGLE_DRAFT_SCTP] = client_;
11570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return parsers;
11590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::OnTransportRequestSignaling(Transport* transport) {
11620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
11630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportProxy* transproxy = GetTransportProxy(transport);
11640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(transproxy != NULL);
11650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (transproxy) {
11660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Reset candidate allocation status for the transport proxy.
11670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    transproxy->set_candidates_allocated(false);
11680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalRequestSignaling(this);
11700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::OnTransportConnecting(Transport* transport) {
11730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // This is an indication that we should begin watching the writability
11740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // state of the transport.
11750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  OnTransportWritable(transport);
11760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::OnTransportWritable(Transport* transport) {
11790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
11800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If the transport is not writable, start a timer to make sure that it
11820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // becomes writable within a reasonable amount of time.  If it does not, we
11830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // terminate since we can't actually send data.  If the transport is writable,
11840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // cancel the timer.  Note that writability transitions may occur repeatedly
11850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // during the lifetime of the session.
11860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  signaling_thread()->Clear(this, MSG_TIMEOUT);
11870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (transport->HasChannels() && !transport->writable()) {
11880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    signaling_thread()->PostDelayed(
11890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        session_manager_->session_timeout() * 1000, this, MSG_TIMEOUT);
11900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
11910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
11920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
11930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::OnTransportProxyCandidatesReady(TransportProxy* transproxy,
11940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                              const Candidates& candidates) {
11950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
11960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (transproxy != NULL) {
11970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (initiator() && !initiate_acked_) {
11980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // TODO: This is to work around server re-ordering
11990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // messages.  We send the candidates once the session-initiate
12000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // is acked.  Once we have fixed the server to guarantee message
12010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // order, we can remove this case.
12020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      transproxy->AddUnsentCandidates(candidates);
12030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else {
12040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!transproxy->negotiated()) {
12050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        transproxy->AddSentCandidates(candidates);
12060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
12070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      SessionError error;
12080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!SendTransportInfoMessage(transproxy, candidates, &error)) {
12090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LOG(LS_ERROR) << "Could not send transport info message: "
12100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      << error.text;
12110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return;
12120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
12130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
12140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
12160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::OnTransportSendError(Transport* transport,
12180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   const buzz::XmlElement* stanza,
12190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   const buzz::QName& name,
12200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   const std::string& type,
12210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   const std::string& text,
12220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   const buzz::XmlElement* extra_info) {
12230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
12240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalErrorMessage(this, stanza, name, type, text, extra_info);
12250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
12260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::OnIncomingMessage(const SessionMessage& msg) {
12280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
12290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(state() == STATE_INIT || msg.from == remote_name());
12300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (current_protocol_== PROTOCOL_HYBRID) {
12320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (msg.protocol == PROTOCOL_GINGLE) {
12330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      current_protocol_ = PROTOCOL_GINGLE;
12340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    } else {
12350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      current_protocol_ = PROTOCOL_JINGLE;
12360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
12370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  bool valid = false;
12400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MessageError error;
12410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (msg.type) {
12420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case ACTION_SESSION_INITIATE:
12430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      valid = OnInitiateMessage(msg, &error);
12440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case ACTION_SESSION_INFO:
12460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      valid = OnInfoMessage(msg);
12470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case ACTION_SESSION_ACCEPT:
12490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      valid = OnAcceptMessage(msg, &error);
12500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case ACTION_SESSION_REJECT:
12520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      valid = OnRejectMessage(msg, &error);
12530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case ACTION_SESSION_TERMINATE:
12550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      valid = OnTerminateMessage(msg, &error);
12560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case ACTION_TRANSPORT_INFO:
12580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      valid = OnTransportInfoMessage(msg, &error);
12590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case ACTION_TRANSPORT_ACCEPT:
12610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      valid = OnTransportAcceptMessage(msg, &error);
12620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case ACTION_DESCRIPTION_INFO:
12640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      valid = OnDescriptionInfoMessage(msg, &error);
12650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
12660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
12670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      valid = BadMessage(buzz::QN_STANZA_BAD_REQUEST,
12680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                         "unknown session message type",
12690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                         &error);
12700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (valid) {
12730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SendAcknowledgementMessage(msg.stanza);
12740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
12750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalErrorMessage(this, msg.stanza, error.type,
12760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                       "modify", error.text, NULL);
12770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
12790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::OnIncomingResponse(const buzz::XmlElement* orig_stanza,
12810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 const buzz::XmlElement* response_stanza,
12820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 const SessionMessage& msg) {
12830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
12840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (msg.type == ACTION_SESSION_INITIATE) {
12860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    OnInitiateAcked();
12870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
12880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
12890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
12900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::OnInitiateAcked() {
129132a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // TODO: This is to work around server re-ordering
129232a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // messages.  We send the candidates once the session-initiate
129332a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // is acked.  Once we have fixed the server to guarantee message
129432a0ac7e336c6132d7a48aa08fe2c912c0eb749etommi@webrtc.org  // order, we can remove this case.
12950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!initiate_acked_) {
12960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    initiate_acked_ = true;
12970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SessionError error;
12980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SendAllUnsentTransportInfoMessages(&error);
12990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
13010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::OnFailedSend(const buzz::XmlElement* orig_stanza,
13030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           const buzz::XmlElement* error_stanza) {
13040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ASSERT(signaling_thread()->IsCurrent());
13050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionMessage msg;
13070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ParseError parse_error;
13080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!ParseSessionMessage(orig_stanza, &msg, &parse_error)) {
13090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Error parsing failed send: " << parse_error.text
13100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  << ":" << orig_stanza;
13110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
13120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If the error is a session redirect, call OnRedirectError, which will
13150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // continue the session with a new remote JID.
13160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionRedirect redirect;
13170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (FindSessionRedirect(error_stanza, &redirect)) {
13180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SessionError error;
13190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!OnRedirectError(redirect, &error)) {
13200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // TODO: Should we send a message back?  The standard
13210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // says nothing about it.
1322f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      std::ostringstream desc;
1323f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      desc << "Failed to redirect: " << error.text;
1324f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      LOG(LS_ERROR) << desc.str();
1325f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org      SetError(ERROR_RESPONSE, desc.str());
13260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
13270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
13280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  std::string error_type = "cancel";
13310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  const buzz::XmlElement* error = error_stanza->FirstNamed(buzz::QN_ERROR);
13330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (error) {
13340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    error_type = error->Attr(buzz::QN_TYPE);
13350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Session error:\n" << error->Str() << "\n"
13370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                  << "in response to:\n" << orig_stanza->Str();
13380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
13390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // don't crash if <error> is missing
13400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_ERROR) << "Session error without <error/> element, ignoring";
13410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return;
13420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (msg.type == ACTION_TRANSPORT_INFO) {
13450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // Transport messages frequently generate errors because they are sent right
13460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // when we detect a network failure.  For that reason, we ignore such
13470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // errors, because if we do not establish writability again, we will
13480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // terminate anyway.  The exceptions are transport-specific error tags,
13490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // which we pass on to the respective transport.
13500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else if ((error_type != "continue") && (error_type != "wait")) {
13510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // We do not set an error if the other side said it is okay to continue
13520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // (possibly after waiting).  These errors can be ignored.
1353f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org    SetError(ERROR_RESPONSE, "");
13540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
13560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnInitiateMessage(const SessionMessage& msg,
13580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                MessageError* error) {
13590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!CheckState(STATE_INIT, error))
13600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
13610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionInitiate init;
13630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!ParseSessionInitiate(msg.protocol, msg.action_elem,
13640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            GetContentParsers(), GetTransportParsers(),
13650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            GetCandidateTranslators(),
13660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            &init, error))
13670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
13680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionError session_error;
13700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!CreateTransportProxies(init.transports, &session_error)) {
13710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return BadMessage(buzz::QN_STANZA_NOT_ACCEPTABLE,
13720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      session_error.text, error);
13730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_remote_name(msg.from);
13760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_initiator_name(msg.initiator);
13770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_remote_description(new SessionDescription(init.ClearContents(),
13780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                init.transports,
13790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                init.groups));
13800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Updating transport with TransportDescription.
1381f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  PushdownTransportDescription(CS_REMOTE, CA_OFFER, NULL);
13820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetState(STATE_RECEIVEDINITIATE);
13830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Users of Session may listen to state change and call Reject().
13850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (state() != STATE_SENTREJECT) {
13860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!OnRemoteCandidates(init.transports, error))
13870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
13880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // TODO(juberti): Auto-generate and push down the local transport answer.
13900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // This is necessary for trickling to work with RFC 5245 ICE.
13910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
13920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
13930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
13940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnAcceptMessage(const SessionMessage& msg, MessageError* error) {
13960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!CheckState(STATE_SENTINITIATE, error))
13970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
13980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
13990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionAccept accept;
14000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!ParseSessionAccept(msg.protocol, msg.action_elem,
14010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          GetContentParsers(), GetTransportParsers(),
14020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          GetCandidateTranslators(),
14030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          &accept, error)) {
14040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
14050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // If we get an accept, we can assume the initiate has been
14080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // received, even if we haven't gotten an IQ response.
14090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  OnInitiateAcked();
14100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_remote_description(new SessionDescription(accept.ClearContents(),
14120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                accept.transports,
14130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                                accept.groups));
14140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Updating transport with TransportDescription.
1415f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  PushdownTransportDescription(CS_REMOTE, CA_ANSWER, NULL);
14160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MaybeEnableMuxingSupport();  // Enable transport channel mux if supported.
14170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetState(STATE_RECEIVEDACCEPT);
14180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!OnRemoteCandidates(accept.transports, error))
14200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
14210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
14230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
14240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnRejectMessage(const SessionMessage& msg, MessageError* error) {
14260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!CheckState(STATE_SENTINITIATE, error))
14270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
14280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetState(STATE_RECEIVEDREJECT);
14300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
14310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
14320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnInfoMessage(const SessionMessage& msg) {
14340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalInfoMessage(this, msg.action_elem);
14350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
14360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
14370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnTerminateMessage(const SessionMessage& msg,
14390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 MessageError* error) {
14400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionTerminate term;
14410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!ParseSessionTerminate(msg.protocol, msg.action_elem, &term, error))
14420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
14430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalReceivedTerminateReason(this, term.reason);
14450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (term.debug_reason != buzz::STR_EMPTY) {
14460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    LOG(LS_VERBOSE) << "Received error on call: " << term.debug_reason;
14470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SetState(STATE_RECEIVEDTERMINATE);
14500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
14510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
14520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnTransportInfoMessage(const SessionMessage& msg,
14540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                     MessageError* error) {
14550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportInfos tinfos;
14560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!ParseTransportInfos(msg.protocol, msg.action_elem,
14570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           initiator_description()->contents(),
14580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           GetTransportParsers(), GetCandidateTranslators(),
14590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                           &tinfos, error))
14600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
14610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!OnRemoteCandidates(tinfos, error))
14630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
14640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
14660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
14670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnTransportAcceptMessage(const SessionMessage& msg,
14690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                       MessageError* error) {
14700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO: Currently here only for compatibility with
14710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Gingle 1.1 clients (notably, Google Voice).
14720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
14730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
14740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnDescriptionInfoMessage(const SessionMessage& msg,
14760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              MessageError* error) {
14770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!CheckState(STATE_INPROGRESS, error))
14780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
14790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  DescriptionInfo description_info;
14810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!ParseDescriptionInfo(msg.protocol, msg.action_elem,
14820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            GetContentParsers(), GetTransportParsers(),
14830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            GetCandidateTranslators(),
14840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                            &description_info, error)) {
14850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
14860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
14870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14887162d28d68ad58802a5a52eca0df59150ee7b9d4henrike@webrtc.org  ContentInfos& updated_contents = description_info.contents;
14890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
14900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO: Currently, reflector sends back
14910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // video stream updates even for an audio-only call, which causes
14920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // this to fail.  Put this back once reflector is fixed.
14930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //
14940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // ContentInfos::iterator it;
14950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // First, ensure all updates are valid before modifying remote_description_.
14960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // for (it = updated_contents.begin(); it != updated_contents.end(); ++it) {
14970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //   if (remote_description()->GetContentByName(it->name) == NULL) {
14980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //     return false;
14990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //   }
15000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // }
15010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // TODO: We used to replace contents from an update, but
15030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // that no longer works with partial updates.  We need to figure out
15040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // a way to merge patial updates into contents.  For now, users of
15050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // Session should listen to SignalRemoteDescriptionUpdate and handle
15060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // updates.  They should not expect remote_description to be the
15070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // latest value.
15080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //
15090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // for (it = updated_contents.begin(); it != updated_contents.end(); ++it) {
15100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //     remote_description()->RemoveContentByName(it->name);
15110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //     remote_description()->AddContent(it->name, it->type, it->description);
15120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  //   }
15130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // }
15140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalRemoteDescriptionUpdate(this, updated_contents);
15160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
15170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool BareJidsEqual(const std::string& name1,
15200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                   const std::string& name2) {
15210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  buzz::Jid jid1(name1);
15220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  buzz::Jid jid2(name2);
15230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return jid1.IsValid() && jid2.IsValid() && jid1.BareEquals(jid2);
15250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::OnRedirectError(const SessionRedirect& redirect,
15280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              SessionError* error) {
15290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  MessageError message_error;
15300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!CheckState(STATE_SENTINITIATE, &message_error)) {
15310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return BadWrite(message_error.text, error);
15320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!BareJidsEqual(remote_name(), redirect.target))
15350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return BadWrite("Redirection not allowed: must be the same bare jid.",
15360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                    error);
15370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // When we receive a redirect, we point the session at the new JID
15390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // and resend the candidates.
15400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  set_remote_name(redirect.target);
15410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return (SendInitiateMessage(local_description(), error) &&
15420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org          ResendAllTransportInfoMessages(error));
15430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::CheckState(State expected, MessageError* error) {
15460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (state() != expected) {
15470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // The server can deliver messages out of order/repeated for various
15480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // reasons. For example, if the server does not recive our iq response,
15490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // it could assume that the iq it sent was lost, and will then send
15500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // it again. Ideally, we should implement reliable messaging with
15510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    // duplicate elimination.
15520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return BadMessage(buzz::QN_STANZA_NOT_ALLOWED,
15530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      "message not allowed in current state",
15540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      error);
15550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
15570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1559f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.orgvoid Session::SetError(Error error, const std::string& error_desc) {
1560f32dd31e14521d7f845e7776af6d44d411573370sergeyu@chromium.org  BaseSession::SetError(error, error_desc);
15610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (error != ERROR_NONE)
15620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    signaling_thread()->Post(this, MSG_ERROR);
15630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15652a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.orgvoid Session::OnMessage(rtc::Message* pmsg) {
15660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  // preserve this because BaseSession::OnMessage may modify it
15670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  State orig_state = state();
15680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  BaseSession::OnMessage(pmsg);
15700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  switch (pmsg->message_id) {
15720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  case MSG_ERROR:
15730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    TerminateWithReason(STR_TERMINATE_ERROR);
15740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    break;
15750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  case MSG_STATE:
15770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    switch (orig_state) {
15780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_SENTREJECT:
15790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_RECEIVEDREJECT:
15800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Assume clean termination.
15810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      Terminate();
15820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
15830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_SENTTERMINATE:
15850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    case STATE_RECEIVEDTERMINATE:
15860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      session_manager_->DestroySession(this);
15870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
15880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    default:
15900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      // Explicitly ignoring some states here.
15910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      break;
15920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
15930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    break;
15940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
15950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
15960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
15970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendInitiateMessage(const SessionDescription* sdesc,
15980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                  SessionError* error) {
15990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionInitiate init;
16000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  init.contents = sdesc->contents();
16010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  init.transports = GetEmptyTransportInfos(init.contents);
16020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  init.groups = sdesc->groups();
16030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return SendMessage(ACTION_SESSION_INITIATE, init, error);
16040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::WriteSessionAction(
16070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    SignalingProtocol protocol, const SessionInitiate& init,
16080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    XmlElements* elems, WriteError* error) {
16090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return WriteSessionInitiate(protocol, init.contents, init.transports,
16100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              GetContentParsers(), GetTransportParsers(),
16110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              GetCandidateTranslators(), init.groups,
16120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                              elems, error);
16130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendAcceptMessage(const SessionDescription* sdesc,
16160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                SessionError* error) {
16170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElements elems;
16180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!WriteSessionAccept(current_protocol_,
16190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          sdesc->contents(),
16200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          GetEmptyTransportInfos(sdesc->contents()),
16210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          GetContentParsers(), GetTransportParsers(),
16220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          GetCandidateTranslators(), sdesc->groups(),
16230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          &elems, error)) {
16240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
16250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return SendMessage(ACTION_SESSION_ACCEPT, elems, error);
16270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendRejectMessage(const std::string& reason,
16300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                SessionError* error) {
16310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionTerminate term(reason);
16320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return SendMessage(ACTION_SESSION_REJECT, term, error);
16330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendTerminateMessage(const std::string& reason,
16360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                   SessionError* error) {
16370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionTerminate term(reason);
16380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return SendMessage(ACTION_SESSION_TERMINATE, term, error);
16390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::WriteSessionAction(SignalingProtocol protocol,
16420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 const SessionTerminate& term,
16430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 XmlElements* elems, WriteError* error) {
16440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  WriteSessionTerminate(protocol, term, elems);
16450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
16460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendTransportInfoMessage(const TransportInfo& tinfo,
16490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                       SessionError* error) {
16500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return SendMessage(ACTION_TRANSPORT_INFO, tinfo, error);
16510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendTransportInfoMessage(const TransportProxy* transproxy,
16540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                       const Candidates& candidates,
16550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                       SessionError* error) {
16560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return SendTransportInfoMessage(TransportInfo(transproxy->content_name(),
1657a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org      TransportDescription(transproxy->type(), std::vector<std::string>(),
1658a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                           std::string(), std::string(), ICEMODE_FULL,
1659a487db2aeda23ade81f0b2e5fd4d50f874d06a9csergeyu@chromium.org                           CONNECTIONROLE_NONE, NULL, candidates)), error);
16600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::WriteSessionAction(SignalingProtocol protocol,
16630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 const TransportInfo& tinfo,
16640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 XmlElements* elems, WriteError* error) {
16650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  TransportInfos tinfos;
16660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  tinfos.push_back(tinfo);
16670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return WriteTransportInfos(protocol, tinfos,
16680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             GetTransportParsers(), GetCandidateTranslators(),
16690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                             elems, error);
16700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::ResendAllTransportInfoMessages(SessionError* error) {
16730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::const_iterator iter = transport_proxies().begin();
16740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transport_proxies().end(); ++iter) {
16750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    TransportProxy* transproxy = iter->second;
16760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (transproxy->sent_candidates().size() > 0) {
16770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!SendTransportInfoMessage(
16780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org              transproxy, transproxy->sent_candidates(), error)) {
16790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LOG(LS_ERROR) << "Could not resend transport info messages: "
16800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      << error->text;
16810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return false;
16820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
16830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      transproxy->ClearSentCandidates();
16840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
16850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
16860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
16870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
16880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
16890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendAllUnsentTransportInfoMessages(SessionError* error) {
16900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  for (TransportMap::const_iterator iter = transport_proxies().begin();
16910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org       iter != transport_proxies().end(); ++iter) {
16920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    TransportProxy* transproxy = iter->second;
16930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (transproxy->unsent_candidates().size() > 0) {
16940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      if (!SendTransportInfoMessage(
16950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org              transproxy, transproxy->unsent_candidates(), error)) {
16960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        LOG(LS_ERROR) << "Could not send unsent transport info messages: "
16970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                      << error->text;
16980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org        return false;
16990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      }
17000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      transproxy->ClearUnsentCandidates();
17010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    }
17020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
17040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
17050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendMessage(ActionType type, const XmlElements& action_elems,
17070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          SessionError* error) {
17083db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.org    return SendMessage(type, action_elems, remote_name(), error);
17093db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.org}
17103db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.org
17113db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.orgbool Session::SendMessage(ActionType type, const XmlElements& action_elems,
17123db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.org                          const std::string& remote_name, SessionError* error) {
17132a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<buzz::XmlElement> stanza(
17140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      new buzz::XmlElement(buzz::QN_IQ));
17150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionMessage msg(current_protocol_, type, id(), initiator_name());
17173db045861afcaf20aed671c0de15a6ff4ca32d08wu@webrtc.org  msg.to = remote_name;
17180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  WriteSessionMessage(msg, action_elems, stanza.get());
17190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalOutgoingMessage(this, stanza.get());
17210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
17220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
17230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate <typename Action>
17250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::SendMessage(ActionType type, const Action& action,
17260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                          SessionError* error) {
17272a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<buzz::XmlElement> stanza(
17280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      new buzz::XmlElement(buzz::QN_IQ));
17290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!WriteActionMessage(type, action, stanza.get(), error))
17300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
17310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalOutgoingMessage(this, stanza.get());
17330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
17340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
17350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate <typename Action>
17370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::WriteActionMessage(ActionType type, const Action& action,
17380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 buzz::XmlElement* stanza,
17390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 WriteError* error) {
17400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (current_protocol_ == PROTOCOL_HYBRID) {
17410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!WriteActionMessage(PROTOCOL_JINGLE, type, action, stanza, error))
17420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
17430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!WriteActionMessage(PROTOCOL_GINGLE, type, action, stanza, error))
17440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
17450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  } else {
17460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    if (!WriteActionMessage(current_protocol_, type, action, stanza, error))
17470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      return false;
17480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  }
17490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
17500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
17510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtemplate <typename Action>
17530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Session::WriteActionMessage(SignalingProtocol protocol,
17540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 ActionType type, const Action& action,
17550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                                 buzz::XmlElement* stanza, WriteError* error) {
17560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  XmlElements action_elems;
17570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  if (!WriteSessionAction(protocol, action, &action_elems, error))
17580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org    return false;
17590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SessionMessage msg(protocol, type, id(), initiator_name());
17610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  msg.to = remote_name();
17620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  WriteSessionMessage(msg, action_elems, stanza);
17640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  return true;
17650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
17660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Session::SendAcknowledgementMessage(const buzz::XmlElement* stanza) {
17682a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org  rtc::scoped_ptr<buzz::XmlElement> ack(
17690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      new buzz::XmlElement(buzz::QN_IQ));
17700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ack->SetAttr(buzz::QN_TO, remote_name());
17710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ack->SetAttr(buzz::QN_ID, stanza->Attr(buzz::QN_ID));
17720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  ack->SetAttr(buzz::QN_TYPE, "result");
17730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org  SignalOutgoingMessage(this, ack.get());
17750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
17760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
17770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}  // namespace cricket
1778