| /* |
| * libjingle |
| * Copyright 2004--2011, 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/p2p/base/portallocatorsessionproxy.h" |
| |
| #include "talk/p2p/base/portallocator.h" |
| #include "talk/p2p/base/portproxy.h" |
| |
| namespace cricket { |
| |
| PortAllocatorSessionMuxer::PortAllocatorSessionMuxer( |
| PortAllocatorSession* session) |
| : session_(session) { |
| session_->SignalPortReady.connect( |
| this, &PortAllocatorSessionMuxer::OnPortReady); |
| } |
| |
| PortAllocatorSessionMuxer::~PortAllocatorSessionMuxer() { |
| for (size_t i = 0; i < session_proxies_.size(); ++i) |
| delete session_proxies_[i]; |
| |
| SignalDestroyed(this); |
| } |
| |
| void PortAllocatorSessionMuxer::RegisterSessionProxy( |
| PortAllocatorSessionProxy* session_proxy) { |
| session_proxies_.push_back(session_proxy); |
| session_proxy->SignalDestroyed.connect( |
| this, &PortAllocatorSessionMuxer::OnSessionProxyDestroyed); |
| session_proxy->set_impl(session_.get()); |
| } |
| |
| void PortAllocatorSessionMuxer::OnPortReady(PortAllocatorSession* session, |
| Port* port) { |
| ASSERT(session == session_.get()); |
| ports_.push_back(port); |
| port->SignalDestroyed.connect( |
| this, &PortAllocatorSessionMuxer::OnPortDestroyed); |
| } |
| |
| void PortAllocatorSessionMuxer::OnPortDestroyed(Port* port) { |
| std::vector<Port*>::iterator it = |
| std::find(ports_.begin(), ports_.end(), port); |
| if (it != ports_.end()) |
| ports_.erase(it); |
| } |
| |
| void PortAllocatorSessionMuxer::OnSessionProxyDestroyed( |
| PortAllocatorSession* proxy) { |
| std::vector<PortAllocatorSessionProxy*>::iterator it = |
| std::find(session_proxies_.begin(), session_proxies_.end(), proxy); |
| if (it != session_proxies_.end()) |
| session_proxies_.erase(it); |
| |
| if (session_proxies_.empty()) { |
| // Destroy PortAllocatorSession and its associated muxer object if all |
| // proxies belonging to this session are already destroyed. |
| delete this; |
| } |
| } |
| |
| PortAllocatorSessionProxy::~PortAllocatorSessionProxy() { |
| std::map<Port*, PortProxy*>::iterator it; |
| for (it = proxy_ports_.begin(); it != proxy_ports_.end(); it++) |
| delete it->second; |
| |
| SignalDestroyed(this); |
| } |
| |
| void PortAllocatorSessionProxy::set_impl( |
| PortAllocatorSession* session) { |
| impl_ = session; |
| |
| impl_->SignalCandidatesReady.connect( |
| this, &PortAllocatorSessionProxy::OnCandidatesReady); |
| impl_->SignalPortReady.connect( |
| this, &PortAllocatorSessionProxy::OnPortReady); |
| } |
| |
| void PortAllocatorSessionProxy::GetInitialPorts() { |
| ASSERT(impl_ != NULL); |
| impl_->GetInitialPorts(); |
| } |
| |
| void PortAllocatorSessionProxy::StartGetAllPorts() { |
| ASSERT(impl_ != NULL); |
| impl_->StartGetAllPorts(); |
| } |
| |
| void PortAllocatorSessionProxy::StopGetAllPorts() { |
| ASSERT(impl_ != NULL); |
| impl_->StartGetAllPorts(); |
| } |
| |
| bool PortAllocatorSessionProxy::IsGettingAllPorts() { |
| ASSERT(impl_ != NULL); |
| return impl_->IsGettingAllPorts(); |
| } |
| |
| void PortAllocatorSessionProxy::OnPortReady(PortAllocatorSession* session, |
| Port* port) { |
| ASSERT(session == impl_); |
| |
| PortProxy* proxy_port = new PortProxy( |
| port->thread(), port->type(), port->socket_factory(), port->network(), |
| port->ip(), port->min_port(), port->max_port()); |
| proxy_port->set_impl(port); |
| proxy_ports_[port] = proxy_port; |
| SignalPortReady(this, proxy_port); |
| } |
| |
| void PortAllocatorSessionProxy::OnCandidatesReady( |
| PortAllocatorSession* session, |
| const std::vector<Candidate>& candidates) { |
| ASSERT(session == impl_); |
| |
| // Since all proxy sessions share a common PortAllocatorSession, |
| // all Candidates will have name associated with the common PAS. |
| // Change Candidate name with the PortAllocatorSessionProxy name. |
| std::vector<Candidate> our_candidates; |
| for (size_t i = 0; i < candidates.size(); ++i) { |
| Candidate new_local_candidate = candidates[i]; |
| new_local_candidate.set_name(name_); |
| our_candidates.push_back(new_local_candidate); |
| } |
| |
| SignalCandidatesReady(this, our_candidates); |
| } |
| |
| } // namespace cricket |