/* * libjingle * Copyright 2004--2005, Google Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "talk/base/common.h" #include "talk/p2p/base/helpers.h" #include "sessionmanager.h" namespace cricket { SessionManager::SessionManager(PortAllocator *allocator, Thread *worker) { allocator_ = allocator; signaling_thread_ = Thread::Current(); if (worker == NULL) { worker_thread_ = Thread::Current(); } else { worker_thread_ = worker; } timeout_ = 50; } SessionManager::~SessionManager() { // Note: Session::Terminate occurs asynchronously, so it's too late to // delete them now. They better be all gone. ASSERT(session_map_.empty()); //TerminateAll(); } Session *SessionManager::CreateSession(const std::string &name, const std::string& initiator) { return CreateSession(name, SessionID(initiator, CreateRandomId()), false); } Session *SessionManager::CreateSession(const std::string &name, const SessionID& id, bool received_initiate) { Session *session = new Session(this, name, id); session_map_[session->id()] = session; session->SignalRequestSignaling.connect(this, &SessionManager::OnRequestSignaling); SignalSessionCreate(session, received_initiate); return session; } void SessionManager::DestroySession(Session *session) { if (session != NULL) { std::map::iterator it = session_map_.find(session->id()); if (it != session_map_.end()) { SignalSessionDestroy(session); session_map_.erase(it); delete session; } } } Session *SessionManager::GetSession(const SessionID& id) { // If the id isn't present, the [] operator will make a NULL entry std::map::iterator it = session_map_.find(id); if (it != session_map_.end()) return (*it).second; return NULL; } void SessionManager::TerminateAll() { while (session_map_.begin() != session_map_.end()) { Session *session = session_map_.begin()->second; session->Terminate(); } } void SessionManager::OnIncomingError(const SessionMessage &m) { // Incoming signaling error. This means, as the result of trying // to send message m, and error was generated. In all cases, a // session should already exist Session *session; switch (m.type()) { case SessionMessage::TYPE_INITIATE: case SessionMessage::TYPE_ACCEPT: case SessionMessage::TYPE_MODIFY: case SessionMessage::TYPE_CANDIDATES: case SessionMessage::TYPE_REJECT: case SessionMessage::TYPE_TERMINATE: session = GetSession(m.session_id()); break; default: return; } if (session != NULL) session->OnIncomingError(m); } void SessionManager::OnIncomingMessage(const SessionMessage &m) { // In the case of an incoming initiate, there is no session yet, and one needs to be created. // The other cases have sessions already. Session *session; switch (m.type()) { case SessionMessage::TYPE_INITIATE: session = CreateSession(m.name(), m.session_id(), true); break; case SessionMessage::TYPE_ACCEPT: case SessionMessage::TYPE_MODIFY: case SessionMessage::TYPE_CANDIDATES: case SessionMessage::TYPE_REJECT: case SessionMessage::TYPE_REDIRECT: case SessionMessage::TYPE_TERMINATE: session = GetSession(m.session_id()); break; default: return; } if (session != NULL) session->OnIncomingMessage(m); } void SessionManager::OnSignalingReady() { for (std::map::iterator it = session_map_.begin(); it != session_map_.end(); ++it) { it->second->OnSignalingReady(); } } void SessionManager::OnRequestSignaling() { SignalRequestSignaling(); } PortAllocator *SessionManager::port_allocator() const { return allocator_; } Thread *SessionManager::worker_thread() const { return worker_thread_; } Thread *SessionManager::signaling_thread() const { return signaling_thread_; } int SessionManager::session_timeout() { return timeout_; } void SessionManager::set_session_timeout(int timeout) { timeout_ = timeout; } } // namespace cricket