| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "remoting/protocol/pepper_session_manager.h" |
| 6 |
| 7 #include "base/bind.h" |
| 8 #include "remoting/jingle_glue/jingle_info_request.h" |
| 9 #include "remoting/jingle_glue/signal_strategy.h" |
| 10 #include "remoting/protocol/jingle_messages.h" |
| 11 #include "remoting/protocol/pepper_session.h" |
| 12 #include "third_party/libjingle/source/talk/base/socketaddress.h" |
| 13 #include "third_party/libjingle/source/talk/xmllite/xmlelement.h" |
| 14 |
| 15 using buzz::QName; |
| 16 |
| 17 namespace remoting { |
| 18 namespace protocol { |
| 19 |
| 20 PepperSessionManager::PepperSessionManager(pp::Instance* pp_instance) |
| 21 : pp_instance_(pp_instance), |
| 22 signal_strategy_(NULL), |
| 23 listener_(NULL), |
| 24 allow_nat_traversal_(false) { |
| 25 } |
| 26 |
| 27 PepperSessionManager::~PepperSessionManager() { |
| 28 Close(); |
| 29 } |
| 30 |
| 31 void PepperSessionManager::Init( |
| 32 const std::string& local_jid, |
| 33 SignalStrategy* signal_strategy, |
| 34 SessionManager::Listener* listener, |
| 35 crypto::RSAPrivateKey* private_key, |
| 36 const std::string& certificate, |
| 37 bool allow_nat_traversal) { |
| 38 listener_ = listener; |
| 39 local_jid_ = local_jid; |
| 40 signal_strategy_ = signal_strategy; |
| 41 private_key_.reset(private_key); |
| 42 certificate_ = certificate; |
| 43 allow_nat_traversal_ = allow_nat_traversal; |
| 44 |
| 45 signal_strategy_->SetListener(this); |
| 46 |
| 47 // If NAT traversal is enabled then we need to request STUN/Relay info. |
| 48 if (allow_nat_traversal) { |
| 49 jingle_info_request_.reset( |
| 50 new JingleInfoRequest(signal_strategy_->CreateIqRequest(), NULL)); |
| 51 jingle_info_request_->Send(base::Bind( |
| 52 &PepperSessionManager::OnJingleInfo, base::Unretained(this))); |
| 53 } else { |
| 54 listener_->OnSessionManagerInitialized(); |
| 55 } |
| 56 } |
| 57 |
| 58 void PepperSessionManager::OnJingleInfo( |
| 59 const std::string& relay_token, |
| 60 const std::vector<std::string>& relay_hosts, |
| 61 const std::vector<talk_base::SocketAddress>& stun_hosts) { |
| 62 DCHECK(CalledOnValidThread()); |
| 63 |
| 64 // TODO(sergeyu): Add support for multiple STUN/relay servers when |
| 65 // it's implemented in libjingle and P2P Transport API. |
| 66 transport_config_.stun_server = stun_hosts[0].ToString(); |
| 67 transport_config_.relay_server = relay_hosts[0]; |
| 68 transport_config_.relay_token = relay_token; |
| 69 LOG(INFO) << "STUN server: " << transport_config_.stun_server |
| 70 << " Relay server: " << transport_config_.relay_server |
| 71 << " Relay token: " << transport_config_.relay_token; |
| 72 |
| 73 listener_->OnSessionManagerInitialized(); |
| 74 } |
| 75 |
| 76 Session* PepperSessionManager::Connect( |
| 77 const std::string& host_jid, |
| 78 const std::string& host_public_key, |
| 79 const std::string& client_token, |
| 80 CandidateSessionConfig* config, |
| 81 Session::StateChangeCallback* state_change_callback) { |
| 82 PepperSession* session = new PepperSession(this); |
| 83 session->StartConnection(host_jid, host_public_key, client_token, |
| 84 config, state_change_callback); |
| 85 sessions_[session->session_id_] = session; |
| 86 return session; |
| 87 } |
| 88 |
| 89 void PepperSessionManager::Close() { |
| 90 DCHECK(CalledOnValidThread()); |
| 91 |
| 92 // Close() can be called only after all sessions are destroyed. |
| 93 DCHECK(sessions_.empty()); |
| 94 |
| 95 listener_ = NULL; |
| 96 jingle_info_request_.reset(); |
| 97 |
| 98 signal_strategy_->SetListener(NULL); |
| 99 } |
| 100 |
| 101 bool PepperSessionManager::OnIncomingStanza(const buzz::XmlElement* stanza) { |
| 102 if (!JingleMessage::IsJingleMessage(stanza)) |
| 103 return false; |
| 104 |
| 105 JingleMessage message; |
| 106 std::string error; |
| 107 if (!message.ParseXml(stanza, &error)) { |
| 108 SendReply(stanza, JingleMessageReply(JingleMessageReply::BAD_REQUEST)); |
| 109 return true; |
| 110 } |
| 111 |
| 112 if (message.action == JingleMessage::SESSION_INITIATE) { |
| 113 SendReply(stanza, JingleMessageReply( |
| 114 JingleMessageReply::NOT_IMPLEMENTED, |
| 115 "Can't accept sessions on the client")); |
| 116 return true; |
| 117 } |
| 118 |
| 119 SessionsMap::iterator it = sessions_.find(message.sid); |
| 120 if (it == sessions_.end()) { |
| 121 SendReply(stanza, JingleMessageReply(JingleMessageReply::INVALID_SID)); |
| 122 return true; |
| 123 } |
| 124 |
| 125 JingleMessageReply reply; |
| 126 it->second->OnIncomingMessage(message, &reply); |
| 127 SendReply(stanza, reply); |
| 128 return true; |
| 129 } |
| 130 |
| 131 IqRequest* PepperSessionManager::CreateIqRequest() { |
| 132 return signal_strategy_->CreateIqRequest(); |
| 133 } |
| 134 |
| 135 void PepperSessionManager::SendReply(const buzz::XmlElement* original_stanza, |
| 136 const JingleMessageReply& reply) { |
| 137 buzz::XmlElement* stanza = reply.ToXml(original_stanza); |
| 138 signal_strategy_->SendStanza(stanza); |
| 139 } |
| 140 |
| 141 void PepperSessionManager::SessionDestroyed(PepperSession* session) { |
| 142 sessions_.erase(session->session_id_); |
| 143 } |
| 144 |
| 145 } // namespace protocol |
| 146 } // namespace remoting |
| OLD | NEW |