1f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch/* 2f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * libjingle 3f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Copyright 2004--2005, Google Inc. 4f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 5f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * Redistribution and use in source and binary forms, with or without 6f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * modification, are permitted provided that the following conditions are met: 7f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 8f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 1. Redistributions of source code must retain the above copyright notice, 9f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer. 10f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright notice, 11f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * this list of conditions and the following disclaimer in the documentation 12f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * and/or other materials provided with the distribution. 13f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 3. The name of the author may not be used to endorse or promote products 14f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * derived from this software without specific prior written permission. 15f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * 16f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch */ 27f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 28f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/sessionmanager.h" 29f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 30f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/common.h" 31f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/base/helpers.h" 32731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/base/stringencode.h" 33f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/p2p/base/constants.h" 34731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/p2p/base/session.h" 35731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "talk/p2p/base/sessionmessages.h" 36f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmpp/constants.h" 37f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch#include "talk/xmpp/jid.h" 38f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 39f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochnamespace cricket { 40f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 41f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochSessionManager::SessionManager(PortAllocator *allocator, 42f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch talk_base::Thread *worker) { 43f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch allocator_ = allocator; 44f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch signaling_thread_ = talk_base::Thread::Current(); 45f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (worker == NULL) { 46f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch worker_thread_ = talk_base::Thread::Current(); 47f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } else { 48f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch worker_thread_ = worker; 49f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 50f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch timeout_ = 50; 51f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 52f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 53f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochSessionManager::~SessionManager() { 54f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // Note: Session::Terminate occurs asynchronously, so it's too late to 55f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // delete them now. They better be all gone. 56f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(session_map_.empty()); 57f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // TerminateAll(); 58f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 59f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SessionManager::AddClient(const std::string& content_type, 61f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SessionClient* client) { 623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ASSERT(client_map_.find(content_type) == client_map_.end()); 633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick client_map_[content_type] = client; 64f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 65f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid SessionManager::RemoveClient(const std::string& content_type) { 673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ClientMap::iterator iter = client_map_.find(content_type); 68f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(iter != client_map_.end()); 69f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch client_map_.erase(iter); 70f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 71f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 723345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickSessionClient* SessionManager::GetClient(const std::string& content_type) { 733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ClientMap::iterator iter = client_map_.find(content_type); 74f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return (iter != client_map_.end()) ? iter->second : NULL; 75f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 76f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 77731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickSession* SessionManager::CreateSession(const std::string& local_name, 783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick const std::string& content_type) { 79731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return CreateSession(local_name, local_name, 80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick talk_base::ToString(talk_base::CreateRandomId()), 813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick content_type, false); 82f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 83f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 84731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickSession* SessionManager::CreateSession( 85731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& local_name, const std::string& initiator_name, 86731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick const std::string& sid, const std::string& content_type, 87731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick bool received_initiate) { 883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick SessionClient* client = GetClient(content_type); 89f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ASSERT(client != NULL); 90f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 91731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Session* session = new Session(this, local_name, initiator_name, 92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick sid, content_type, client); 93f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session_map_[session->id()] = session; 94f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->SignalRequestSignaling.connect( 95f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, &SessionManager::OnRequestSignaling); 96f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->SignalOutgoingMessage.connect( 97f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch this, &SessionManager::OnOutgoingMessage); 98f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->SignalErrorMessage.connect(this, &SessionManager::OnErrorMessage); 99f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalSessionCreate(session, received_initiate); 100f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->client()->OnSessionCreate(session, received_initiate); 101f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return session; 102f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 103f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 104731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid SessionManager::DestroySession(Session* session) { 105f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (session != NULL) { 106f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SessionMap::iterator it = session_map_.find(session->id()); 107f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (it != session_map_.end()) { 108f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalSessionDestroy(session); 109f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->client()->OnSessionDestroy(session); 110f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session_map_.erase(it); 111f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch delete session; 112f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 113f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 114f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 115f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 116731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickSession* SessionManager::GetSession(const std::string& sid) { 117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionMap::iterator it = session_map_.find(sid); 118f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (it != session_map_.end()) 119f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return it->second; 120f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return NULL; 121f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 122f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 123f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid SessionManager::TerminateAll() { 124f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch while (session_map_.begin() != session_map_.end()) { 125731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Session* session = session_map_.begin()->second; 126f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->Terminate(); 127f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 128f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 129f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 130f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbool SessionManager::IsSessionMessage(const buzz::XmlElement* stanza) { 131f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return cricket::IsSessionMessage(stanza); 132f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 133f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 134f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen MurdochSession* SessionManager::FindSession(const std::string& sid, 135f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& remote_name) { 136731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick SessionMap::iterator iter = session_map_.find(sid); 137f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (iter == session_map_.end()) 138f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return NULL; 139f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 140f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch Session* session = iter->second; 141f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (buzz::Jid(remote_name) != buzz::Jid(session->remote_name())) 142f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return NULL; 143f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 144f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return session; 145f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 146f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 147f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid SessionManager::OnIncomingMessage(const buzz::XmlElement* stanza) { 148f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SessionMessage msg; 149f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ParseError error; 150f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 151f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!ParseSessionMessage(stanza, &msg, &error)) { 152f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify", 153f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error.text, NULL); 154f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 155f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 156f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Session* session = FindSession(msg.sid, msg.from); 158f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (session) { 159f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->OnIncomingMessage(msg); 160f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 161f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 162f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (msg.type != ACTION_SESSION_INITIATE) { 163f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify", 164f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch "unknown session", NULL); 165f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 166f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 167f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string content_type; 169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick if (!ParseContentType(msg.protocol, msg.action_elem, 170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick &content_type, &error)) { 171f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify", 172f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error.text, NULL); 173f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 174f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 175f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!GetClient(content_type)) { 177f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SendErrorMessage(stanza, buzz::QN_STANZA_BAD_REQUEST, "modify", 178731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick "unknown content type: " + content_type, NULL); 179f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 180f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 181f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 182731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick session = CreateSession(msg.to, msg.initiator, msg.sid, 1833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick content_type, true); 184f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->OnIncomingMessage(msg); 185f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 186f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 187f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid SessionManager::OnIncomingResponse(const buzz::XmlElement* orig_stanza, 188f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::XmlElement* response_stanza) { 189f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // We don't do anything with the response now. If we need to we can forward 190f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // it to the session. 191f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return; 192f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 193f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 194f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid SessionManager::OnFailedSend(const buzz::XmlElement* orig_stanza, 195f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::XmlElement* error_stanza) { 196f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SessionMessage msg; 197f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ParseError error; 198f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!ParseSessionMessage(orig_stanza, &msg, &error)) { 199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick return; // TODO: log somewhere? 200f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 201f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick Session* session = FindSession(msg.sid, msg.to); 203f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (session) { 204f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch talk_base::scoped_ptr<buzz::XmlElement> synthetic_error; 205f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (!error_stanza) { 206f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // A failed send is semantically equivalent to an error response, so we 207f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // can just turn the former into the latter. 208f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch synthetic_error.reset( 209f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch CreateErrorMessage(orig_stanza, buzz::QN_STANZA_ITEM_NOT_FOUND, 210f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch "cancel", "Recipient did not respond", NULL)); 211f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error_stanza = synthetic_error.get(); 212f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 213f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 214f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch session->OnFailedSend(orig_stanza, error_stanza); 215f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 216f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 217f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 218f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid SessionManager::SendErrorMessage(const buzz::XmlElement* stanza, 219f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::QName& name, 220f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& type, 221f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& text, 222f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::XmlElement* extra_info) { 223f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch talk_base::scoped_ptr<buzz::XmlElement> msg( 224f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch CreateErrorMessage(stanza, name, type, text, extra_info)); 225f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalOutgoingMessage(this, msg.get()); 226f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 227f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 228f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochbuzz::XmlElement* SessionManager::CreateErrorMessage( 229f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::XmlElement* stanza, 230f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::QName& name, 231f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& type, 232f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& text, 233f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::XmlElement* extra_info) { 234f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buzz::XmlElement* iq = new buzz::XmlElement(buzz::QN_IQ); 235f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq->SetAttr(buzz::QN_TO, stanza->Attr(buzz::QN_FROM)); 236f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq->SetAttr(buzz::QN_ID, stanza->Attr(buzz::QN_ID)); 237f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq->SetAttr(buzz::QN_TYPE, "error"); 238f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick CopyXmlChildren(stanza, iq); 240f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 241f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buzz::XmlElement* error = new buzz::XmlElement(buzz::QN_ERROR); 242f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error->SetAttr(buzz::QN_TYPE, type); 243f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch iq->AddElement(error); 244f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 245f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // If the error name is not in the standard namespace, we have to first add 246f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // some error from that namespace. 247f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (name.Namespace() != buzz::NS_STANZA) { 248f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error->AddElement( 249f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch new buzz::XmlElement(buzz::QN_STANZA_UNDEFINED_CONDITION)); 250f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 251f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error->AddElement(new buzz::XmlElement(name)); 252f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 253f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (extra_info) 254f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error->AddElement(new buzz::XmlElement(*extra_info)); 255f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 256f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch if (text.size() > 0) { 257f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // It's okay to always use English here. This text is for debugging 258f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // purposes only. 259f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch buzz::XmlElement* text_elem = new buzz::XmlElement(buzz::QN_STANZA_TEXT); 260f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch text_elem->SetAttr(buzz::QN_XML_LANG, "en"); 261f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch text_elem->SetBodyText(text); 262f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch error->AddElement(text_elem); 263f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 264f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 265f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch // TODO: Should we include error codes as well for SIP compatibility? 266f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 267f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch return iq; 268f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 269f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 270f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid SessionManager::OnOutgoingMessage(Session* session, 271f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::XmlElement* stanza) { 272f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalOutgoingMessage(this, stanza); 273f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 274f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 275f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid SessionManager::OnErrorMessage(BaseSession* session, 276f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::XmlElement* stanza, 277f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::QName& name, 278f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& type, 279f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const std::string& text, 280f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch const buzz::XmlElement* extra_info) { 281f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SendErrorMessage(stanza, name, type, text, extra_info); 282f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 283f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 284f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid SessionManager::OnSignalingReady() { 285f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch for (SessionMap::iterator it = session_map_.begin(); 286f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch it != session_map_.end(); 287f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch ++it) { 288f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch it->second->OnSignalingReady(); 289f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch } 290f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 291f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 292f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdochvoid SessionManager::OnRequestSignaling(Session* session) { 293f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch SignalRequestSignaling(); 294f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} 295f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch 296f74420b3285b9fe04a7e00aa3b8c0ab07ea344bcBen Murdoch} // namespace cricket 297