1 /* 2 * libjingle 3 * Copyright 2004--2005, Google Inc. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, 9 * this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 3. The name of the author may not be used to endorse or promote products 14 * derived from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #ifndef TALK_P2P_BASE_SESSION_H_ 29 #define TALK_P2P_BASE_SESSION_H_ 30 31 #include <list> 32 #include <map> 33 #include <string> 34 #include <vector> 35 36 #include "talk/p2p/base/parsing.h" 37 #include "talk/p2p/base/port.h" 38 #include "talk/p2p/base/sessionclient.h" 39 #include "talk/p2p/base/sessionmanager.h" 40 #include "talk/p2p/base/sessionmessages.h" 41 #include "talk/p2p/base/transport.h" 42 #include "webrtc/libjingle/xmllite/xmlelement.h" 43 #include "talk/xmpp/constants.h" 44 #include "webrtc/base/refcount.h" 45 #include "webrtc/base/scoped_ptr.h" 46 #include "webrtc/base/scoped_ref_ptr.h" 47 #include "webrtc/base/socketaddress.h" 48 49 namespace cricket { 50 51 class BaseSession; 52 class P2PTransportChannel; 53 class Transport; 54 class TransportChannel; 55 class TransportChannelProxy; 56 class TransportChannelImpl; 57 58 typedef rtc::RefCountedObject<rtc::scoped_ptr<Transport> > 59 TransportWrapper; 60 61 // Used for errors that will send back a specific error message to the 62 // remote peer. We add "type" to the errors because it's needed for 63 // SignalErrorMessage. 64 struct MessageError : ParseError { 65 buzz::QName type; 66 67 // if unset, assume type is a parse error MessageErrorMessageError68 MessageError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {} 69 SetTypeMessageError70 void SetType(const buzz::QName type) { 71 this->type = type; 72 } 73 }; 74 75 // Used for errors that may be returned by public session methods that 76 // can fail. 77 // TODO: Use this error in Session::Initiate and 78 // Session::Accept. 79 struct SessionError : WriteError { 80 }; 81 82 // Bundles a Transport and ChannelMap together. ChannelMap is used to 83 // create transport channels before receiving or sending a session 84 // initiate, and for speculatively connecting channels. Previously, a 85 // session had one ChannelMap and transport. Now, with multiple 86 // transports per session, we need multiple ChannelMaps as well. 87 88 typedef std::map<int, TransportChannelProxy*> ChannelMap; 89 90 class TransportProxy : public sigslot::has_slots<>, 91 public CandidateTranslator { 92 public: TransportProxy(rtc::Thread * worker_thread,const std::string & sid,const std::string & content_name,TransportWrapper * transport)93 TransportProxy( 94 rtc::Thread* worker_thread, 95 const std::string& sid, 96 const std::string& content_name, 97 TransportWrapper* transport) 98 : worker_thread_(worker_thread), 99 sid_(sid), 100 content_name_(content_name), 101 transport_(transport), 102 connecting_(false), 103 negotiated_(false), 104 sent_candidates_(false), 105 candidates_allocated_(false), 106 local_description_set_(false), 107 remote_description_set_(false) { 108 transport_->get()->SignalCandidatesReady.connect( 109 this, &TransportProxy::OnTransportCandidatesReady); 110 } 111 ~TransportProxy(); 112 content_name()113 const std::string& content_name() const { return content_name_; } 114 // TODO(juberti): It's not good form to expose the object you're wrapping, 115 // since callers can mutate it. Can we make this return a const Transport*? impl()116 Transport* impl() const { return transport_->get(); } 117 118 const std::string& type() const; negotiated()119 bool negotiated() const { return negotiated_; } sent_candidates()120 const Candidates& sent_candidates() const { return sent_candidates_; } unsent_candidates()121 const Candidates& unsent_candidates() const { return unsent_candidates_; } candidates_allocated()122 bool candidates_allocated() const { return candidates_allocated_; } set_candidates_allocated(bool allocated)123 void set_candidates_allocated(bool allocated) { 124 candidates_allocated_ = allocated; 125 } 126 127 TransportChannel* GetChannel(int component); 128 TransportChannel* CreateChannel(const std::string& channel_name, 129 int component); 130 bool HasChannel(int component); 131 void DestroyChannel(int component); 132 133 void AddSentCandidates(const Candidates& candidates); 134 void AddUnsentCandidates(const Candidates& candidates); ClearSentCandidates()135 void ClearSentCandidates() { sent_candidates_.clear(); } ClearUnsentCandidates()136 void ClearUnsentCandidates() { unsent_candidates_.clear(); } 137 138 // Start the connection process for any channels, creating impls if needed. 139 void ConnectChannels(); 140 // Hook up impls to the proxy channels. Doesn't change connect state. 141 void CompleteNegotiation(); 142 143 // Mux this proxy onto the specified proxy's transport. 144 bool SetupMux(TransportProxy* proxy); 145 146 // Simple functions that thunk down to the same functions on Transport. 147 void SetIceRole(IceRole role); 148 void SetIdentity(rtc::SSLIdentity* identity); 149 bool SetLocalTransportDescription(const TransportDescription& description, 150 ContentAction action, 151 std::string* error_desc); 152 bool SetRemoteTransportDescription(const TransportDescription& description, 153 ContentAction action, 154 std::string* error_desc); 155 void OnSignalingReady(); 156 bool OnRemoteCandidates(const Candidates& candidates, std::string* error); 157 158 // CandidateTranslator methods. 159 virtual bool GetChannelNameFromComponent( 160 int component, std::string* channel_name) const; 161 virtual bool GetComponentFromChannelName( 162 const std::string& channel_name, int* component) const; 163 164 // Called when a transport signals that it has new candidates. OnTransportCandidatesReady(cricket::Transport * transport,const Candidates & candidates)165 void OnTransportCandidatesReady(cricket::Transport* transport, 166 const Candidates& candidates) { 167 SignalCandidatesReady(this, candidates); 168 } 169 local_description_set()170 bool local_description_set() const { 171 return local_description_set_; 172 } remote_description_set()173 bool remote_description_set() const { 174 return remote_description_set_; 175 } 176 177 // Handles sending of ready candidates and receiving of remote candidates. 178 sigslot::signal2<TransportProxy*, 179 const std::vector<Candidate>&> SignalCandidatesReady; 180 181 private: 182 TransportChannelProxy* GetChannelProxy(int component) const; 183 TransportChannelProxy* GetChannelProxyByName(const std::string& name) const; 184 185 TransportChannelImpl* GetOrCreateChannelProxyImpl(int component); 186 TransportChannelImpl* GetOrCreateChannelProxyImpl_w(int component); 187 188 // Manipulators of transportchannelimpl in channel proxy. 189 void SetupChannelProxy(int component, 190 TransportChannelProxy* proxy); 191 void SetupChannelProxy_w(int component, 192 TransportChannelProxy* proxy); 193 void ReplaceChannelProxyImpl(TransportChannelProxy* proxy, 194 TransportChannelImpl* impl); 195 void ReplaceChannelProxyImpl_w(TransportChannelProxy* proxy, 196 TransportChannelImpl* impl); 197 198 rtc::Thread* const worker_thread_; 199 const std::string sid_; 200 const std::string content_name_; 201 rtc::scoped_refptr<TransportWrapper> transport_; 202 bool connecting_; 203 bool negotiated_; 204 ChannelMap channels_; 205 Candidates sent_candidates_; 206 Candidates unsent_candidates_; 207 bool candidates_allocated_; 208 bool local_description_set_; 209 bool remote_description_set_; 210 }; 211 212 typedef std::map<std::string, TransportProxy*> TransportMap; 213 214 // Statistics for all the transports of this session. 215 typedef std::map<std::string, TransportStats> TransportStatsMap; 216 typedef std::map<std::string, std::string> ProxyTransportMap; 217 218 struct SessionStats { 219 ProxyTransportMap proxy_to_transport; 220 TransportStatsMap transport_stats; 221 }; 222 223 // A BaseSession manages general session state. This includes negotiation 224 // of both the application-level and network-level protocols: the former 225 // defines what will be sent and the latter defines how it will be sent. Each 226 // network-level protocol is represented by a Transport object. Each Transport 227 // participates in the network-level negotiation. The individual streams of 228 // packets are represented by TransportChannels. The application-level protocol 229 // is represented by SessionDecription objects. 230 class BaseSession : public sigslot::has_slots<>, 231 public rtc::MessageHandler { 232 public: 233 enum { 234 MSG_TIMEOUT = 0, 235 MSG_ERROR, 236 MSG_STATE, 237 }; 238 239 enum State { 240 STATE_INIT = 0, 241 STATE_SENTINITIATE, // sent initiate, waiting for Accept or Reject 242 STATE_RECEIVEDINITIATE, // received an initiate. Call Accept or Reject 243 STATE_SENTPRACCEPT, // sent provisional Accept 244 STATE_SENTACCEPT, // sent accept. begin connecting transport 245 STATE_RECEIVEDPRACCEPT, // received provisional Accept, waiting for Accept 246 STATE_RECEIVEDACCEPT, // received accept. begin connecting transport 247 STATE_SENTMODIFY, // sent modify, waiting for Accept or Reject 248 STATE_RECEIVEDMODIFY, // received modify, call Accept or Reject 249 STATE_SENTREJECT, // sent reject after receiving initiate 250 STATE_RECEIVEDREJECT, // received reject after sending initiate 251 STATE_SENTREDIRECT, // sent direct after receiving initiate 252 STATE_SENTTERMINATE, // sent terminate (any time / either side) 253 STATE_RECEIVEDTERMINATE, // received terminate (any time / either side) 254 STATE_INPROGRESS, // session accepted and in progress 255 STATE_DEINIT, // session is being destroyed 256 }; 257 258 enum Error { 259 ERROR_NONE = 0, // no error 260 ERROR_TIME = 1, // no response to signaling 261 ERROR_RESPONSE = 2, // error during signaling 262 ERROR_NETWORK = 3, // network error, could not allocate network resources 263 ERROR_CONTENT = 4, // channel errors in SetLocalContent/SetRemoteContent 264 ERROR_TRANSPORT = 5, // transport error of some kind 265 }; 266 267 // Convert State to a readable string. 268 static std::string StateToString(State state); 269 270 BaseSession(rtc::Thread* signaling_thread, 271 rtc::Thread* worker_thread, 272 PortAllocator* port_allocator, 273 const std::string& sid, 274 const std::string& content_type, 275 bool initiator); 276 virtual ~BaseSession(); 277 278 // These are const to allow them to be called from const methods. signaling_thread()279 rtc::Thread* signaling_thread() const { return signaling_thread_; } worker_thread()280 rtc::Thread* worker_thread() const { return worker_thread_; } port_allocator()281 PortAllocator* port_allocator() const { return port_allocator_; } 282 283 // The ID of this session. id()284 const std::string& id() const { return sid_; } 285 286 // TODO(juberti): This data is largely redundant, as it can now be obtained 287 // from local/remote_description(). Remove these functions and members. 288 // Returns the XML namespace identifying the type of this session. content_type()289 const std::string& content_type() const { return content_type_; } 290 // Returns the XML namespace identifying the transport used for this session. transport_type()291 const std::string& transport_type() const { return transport_type_; } 292 293 // Indicates whether we initiated this session. initiator()294 bool initiator() const { return initiator_; } 295 296 // Returns the application-level description given by our client. 297 // If we are the recipient, this will be NULL until we send an accept. 298 const SessionDescription* local_description() const; 299 300 // Returns the application-level description given by the other client. 301 // If we are the initiator, this will be NULL until we receive an accept. 302 const SessionDescription* remote_description() const; 303 304 SessionDescription* remote_description(); 305 306 // Takes ownership of SessionDescription* 307 void set_local_description(const SessionDescription* sdesc); 308 309 // Takes ownership of SessionDescription* 310 void set_remote_description(SessionDescription* sdesc); 311 312 const SessionDescription* initiator_description() const; 313 314 // Returns the current state of the session. See the enum above for details. 315 // Each time the state changes, we will fire this signal. state()316 State state() const { return state_; } 317 sigslot::signal2<BaseSession* , State> SignalState; 318 319 // Returns the last error in the session. See the enum above for details. 320 // Each time the an error occurs, we will fire this signal. error()321 Error error() const { return error_; } error_desc()322 const std::string& error_desc() const { return error_desc_; } 323 sigslot::signal2<BaseSession* , Error> SignalError; 324 325 // Updates the state, signaling if necessary. 326 virtual void SetState(State state); 327 328 // Updates the error state, signaling if necessary. 329 // TODO(ronghuawu): remove the SetError method that doesn't take |error_desc|. 330 virtual void SetError(Error error, const std::string& error_desc); 331 332 // Fired when the remote description is updated, with the updated 333 // contents. 334 sigslot::signal2<BaseSession* , const ContentInfos&> 335 SignalRemoteDescriptionUpdate; 336 337 // Fired when SetState is called (regardless if there's a state change), which 338 // indicates the session description might have be updated. 339 sigslot::signal2<BaseSession*, ContentAction> SignalNewLocalDescription; 340 341 // Fired when SetState is called (regardless if there's a state change), which 342 // indicates the session description might have be updated. 343 sigslot::signal2<BaseSession*, ContentAction> SignalNewRemoteDescription; 344 345 // Returns the transport that has been negotiated or NULL if 346 // negotiation is still in progress. 347 virtual Transport* GetTransport(const std::string& content_name); 348 349 // Creates a new channel with the given names. This method may be called 350 // immediately after creating the session. However, the actual 351 // implementation may not be fixed until transport negotiation completes. 352 // This will usually be called from the worker thread, but that 353 // shouldn't be an issue since the main thread will be blocked in 354 // Send when doing so. 355 virtual TransportChannel* CreateChannel(const std::string& content_name, 356 const std::string& channel_name, 357 int component); 358 359 // Returns the channel with the given names. 360 virtual TransportChannel* GetChannel(const std::string& content_name, 361 int component); 362 363 // Destroys the channel with the given names. 364 // This will usually be called from the worker thread, but that 365 // shouldn't be an issue since the main thread will be blocked in 366 // Send when doing so. 367 virtual void DestroyChannel(const std::string& content_name, 368 int component); 369 370 // Returns stats for all channels of all transports. 371 // This avoids exposing the internal structures used to track them. 372 virtual bool GetStats(SessionStats* stats); 373 identity()374 rtc::SSLIdentity* identity() { return identity_; } 375 376 protected: 377 // Specifies the identity to use in this session. 378 bool SetIdentity(rtc::SSLIdentity* identity); 379 380 bool PushdownTransportDescription(ContentSource source, 381 ContentAction action, 382 std::string* error_desc); set_initiator(bool initiator)383 void set_initiator(bool initiator) { initiator_ = initiator; } 384 transport_proxies()385 const TransportMap& transport_proxies() const { return transports_; } 386 // Get a TransportProxy by content_name or transport. NULL if not found. 387 TransportProxy* GetTransportProxy(const std::string& content_name); 388 TransportProxy* GetTransportProxy(const Transport* transport); 389 TransportProxy* GetFirstTransportProxy(); 390 void DestroyTransportProxy(const std::string& content_name); 391 // TransportProxy is owned by session. Return proxy just for convenience. 392 TransportProxy* GetOrCreateTransportProxy(const std::string& content_name); 393 // Creates the actual transport object. Overridable for testing. 394 virtual Transport* CreateTransport(const std::string& content_name); 395 396 void OnSignalingReady(); 397 void SpeculativelyConnectAllTransportChannels(); 398 // Helper method to provide remote candidates to the transport. 399 bool OnRemoteCandidates(const std::string& content_name, 400 const Candidates& candidates, 401 std::string* error); 402 403 // This method will mux transport channels by content_name. 404 // First content is used for muxing. 405 bool MaybeEnableMuxingSupport(); 406 407 // Called when a transport requests signaling. OnTransportRequestSignaling(Transport * transport)408 virtual void OnTransportRequestSignaling(Transport* transport) { 409 } 410 411 // Called when the first channel of a transport begins connecting. We use 412 // this to start a timer, to make sure that the connection completes in a 413 // reasonable amount of time. OnTransportConnecting(Transport * transport)414 virtual void OnTransportConnecting(Transport* transport) { 415 } 416 417 // Called when a transport changes its writable state. We track this to make 418 // sure that the transport becomes writable within a reasonable amount of 419 // time. If this does not occur, we signal an error. OnTransportWritable(Transport * transport)420 virtual void OnTransportWritable(Transport* transport) { 421 } OnTransportReadable(Transport * transport)422 virtual void OnTransportReadable(Transport* transport) { 423 } 424 425 // Called when a transport has found its steady-state connections. OnTransportCompleted(Transport * transport)426 virtual void OnTransportCompleted(Transport* transport) { 427 } 428 429 // Called when a transport has failed permanently. OnTransportFailed(Transport * transport)430 virtual void OnTransportFailed(Transport* transport) { 431 } 432 433 // Called when a transport signals that it has new candidates. OnTransportProxyCandidatesReady(TransportProxy * proxy,const Candidates & candidates)434 virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy, 435 const Candidates& candidates) { 436 } 437 438 // Called when a transport signals that it found an error in an incoming 439 // message. OnTransportSendError(Transport * transport,const buzz::XmlElement * stanza,const buzz::QName & name,const std::string & type,const std::string & text,const buzz::XmlElement * extra_info)440 virtual void OnTransportSendError(Transport* transport, 441 const buzz::XmlElement* stanza, 442 const buzz::QName& name, 443 const std::string& type, 444 const std::string& text, 445 const buzz::XmlElement* extra_info) { 446 } 447 OnTransportRouteChange(Transport * transport,int component,const cricket::Candidate & remote_candidate)448 virtual void OnTransportRouteChange( 449 Transport* transport, 450 int component, 451 const cricket::Candidate& remote_candidate) { 452 } 453 454 virtual void OnTransportCandidatesAllocationDone(Transport* transport); 455 456 // Called when all transport channels allocated required candidates. 457 // This method should be used as an indication of candidates gathering process 458 // is completed and application can now send local candidates list to remote. OnCandidatesAllocationDone()459 virtual void OnCandidatesAllocationDone() { 460 } 461 462 // Handles the ice role change callback from Transport. This must be 463 // propagated to all the transports. 464 virtual void OnRoleConflict(); 465 466 // Handles messages posted to us. 467 virtual void OnMessage(rtc::Message *pmsg); 468 469 protected: 470 State state_; 471 Error error_; 472 std::string error_desc_; 473 474 private: 475 // Helper methods to push local and remote transport descriptions. 476 bool PushdownLocalTransportDescription( 477 const SessionDescription* sdesc, ContentAction action, 478 std::string* error_desc); 479 bool PushdownRemoteTransportDescription( 480 const SessionDescription* sdesc, ContentAction action, 481 std::string* error_desc); 482 483 bool IsCandidateAllocationDone() const; 484 void MaybeCandidateAllocationDone(); 485 486 // This method will delete the Transport and TransportChannelImpls and 487 // replace those with the selected Transport objects. Selection is done 488 // based on the content_name and in this case first MediaContent information 489 // is used for mux. 490 bool SetSelectedProxy(const std::string& content_name, 491 const ContentGroup* muxed_group); 492 // Log session state. 493 void LogState(State old_state, State new_state); 494 495 // Returns true and the TransportInfo of the given |content_name| 496 // from |description|. Returns false if it's not available. 497 static bool GetTransportDescription(const SessionDescription* description, 498 const std::string& content_name, 499 TransportDescription* info); 500 501 // Fires the new description signal according to the current state. 502 void SignalNewDescription(); 503 504 // Gets the ContentAction and ContentSource according to the session state. 505 bool GetContentAction(ContentAction* action, ContentSource* source); 506 507 rtc::Thread* const signaling_thread_; 508 rtc::Thread* const worker_thread_; 509 PortAllocator* const port_allocator_; 510 const std::string sid_; 511 const std::string content_type_; 512 const std::string transport_type_; 513 bool initiator_; 514 rtc::SSLIdentity* identity_; 515 rtc::scoped_ptr<const SessionDescription> local_description_; 516 rtc::scoped_ptr<SessionDescription> remote_description_; 517 uint64 ice_tiebreaker_; 518 // This flag will be set to true after the first role switch. This flag 519 // will enable us to stop any role switch during the call. 520 bool role_switch_; 521 TransportMap transports_; 522 }; 523 524 // A specific Session created by the SessionManager, using XMPP for protocol. 525 class Session : public BaseSession { 526 public: 527 // Returns the manager that created and owns this session. session_manager()528 SessionManager* session_manager() const { return session_manager_; } 529 530 // Returns the client that is handling the application data of this session. client()531 SessionClient* client() const { return client_; } 532 533 // Returns the JID of this client. local_name()534 const std::string& local_name() const { return local_name_; } 535 536 // Returns the JID of the other peer in this session. remote_name()537 const std::string& remote_name() const { return remote_name_; } 538 539 // Set the JID of the other peer in this session. 540 // Typically the remote_name_ is set when the session is initiated. 541 // However, sometimes (e.g when a proxy is used) the peer name is 542 // known after the BaseSession has been initiated and it must be updated 543 // explicitly. set_remote_name(const std::string & name)544 void set_remote_name(const std::string& name) { remote_name_ = name; } 545 546 // Set the JID of the initiator of this session. Allows for the overriding 547 // of the initiator to be a third-party, eg. the MUC JID when creating p2p 548 // sessions. set_initiator_name(const std::string & name)549 void set_initiator_name(const std::string& name) { initiator_name_ = name; } 550 551 // Indicates the JID of the entity who initiated this session. 552 // In special cases, may be different than both local_name and remote_name. initiator_name()553 const std::string& initiator_name() const { return initiator_name_; } 554 current_protocol()555 SignalingProtocol current_protocol() const { return current_protocol_; } 556 set_current_protocol(SignalingProtocol protocol)557 void set_current_protocol(SignalingProtocol protocol) { 558 current_protocol_ = protocol; 559 } 560 561 // Updates the error state, signaling if necessary. 562 virtual void SetError(Error error, const std::string& error_desc); 563 564 // When the session needs to send signaling messages, it beings by requesting 565 // signaling. The client should handle this by calling OnSignalingReady once 566 // it is ready to send the messages. 567 // (These are called only by SessionManager.) 568 sigslot::signal1<Session*> SignalRequestSignaling; OnSignalingReady()569 void OnSignalingReady() { BaseSession::OnSignalingReady(); } 570 571 // Takes ownership of session description. 572 // TODO: Add an error argument to pass back to the caller. 573 bool Initiate(const std::string& to, 574 const SessionDescription* sdesc); 575 576 // When we receive an initiate, we create a session in the 577 // RECEIVEDINITIATE state and respond by accepting or rejecting. 578 // Takes ownership of session description. 579 // TODO: Add an error argument to pass back to the caller. 580 bool Accept(const SessionDescription* sdesc); 581 bool Reject(const std::string& reason); Terminate()582 bool Terminate() { 583 return TerminateWithReason(STR_TERMINATE_SUCCESS); 584 } 585 bool TerminateWithReason(const std::string& reason); 586 // Fired whenever we receive a terminate message along with a reason 587 sigslot::signal2<Session*, const std::string&> SignalReceivedTerminateReason; 588 589 // The two clients in the session may also send one another 590 // arbitrary XML messages, which are called "info" messages. Sending 591 // takes ownership of the given elements. The signal does not; the 592 // parent element will be deleted after the signal. 593 bool SendInfoMessage(const XmlElements& elems, 594 const std::string& remote_name); 595 bool SendDescriptionInfoMessage(const ContentInfos& contents); 596 sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage; 597 598 private: 599 // Creates or destroys a session. (These are called only SessionManager.) 600 Session(SessionManager *session_manager, 601 const std::string& local_name, const std::string& initiator_name, 602 const std::string& sid, const std::string& content_type, 603 SessionClient* client); 604 ~Session(); 605 // For each transport info, create a transport proxy. Can fail for 606 // incompatible transport types. 607 bool CreateTransportProxies(const TransportInfos& tinfos, 608 SessionError* error); 609 bool OnRemoteCandidates(const TransportInfos& tinfos, 610 ParseError* error); 611 // Returns a TransportInfo without candidates for each content name. 612 // Uses the transport_type_ of the session. 613 TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const; 614 615 // Maps passed to serialization functions. 616 TransportParserMap GetTransportParsers(); 617 ContentParserMap GetContentParsers(); 618 CandidateTranslatorMap GetCandidateTranslators(); 619 620 virtual void OnTransportRequestSignaling(Transport* transport); 621 virtual void OnTransportConnecting(Transport* transport); 622 virtual void OnTransportWritable(Transport* transport); 623 virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy, 624 const Candidates& candidates); 625 virtual void OnTransportSendError(Transport* transport, 626 const buzz::XmlElement* stanza, 627 const buzz::QName& name, 628 const std::string& type, 629 const std::string& text, 630 const buzz::XmlElement* extra_info); 631 virtual void OnMessage(rtc::Message *pmsg); 632 633 // Send various kinds of session messages. 634 bool SendInitiateMessage(const SessionDescription* sdesc, 635 SessionError* error); 636 bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error); 637 bool SendRejectMessage(const std::string& reason, SessionError* error); 638 bool SendTerminateMessage(const std::string& reason, SessionError* error); 639 bool SendTransportInfoMessage(const TransportInfo& tinfo, 640 SessionError* error); 641 bool SendTransportInfoMessage(const TransportProxy* transproxy, 642 const Candidates& candidates, 643 SessionError* error); 644 645 bool ResendAllTransportInfoMessages(SessionError* error); 646 bool SendAllUnsentTransportInfoMessages(SessionError* error); 647 648 // All versions of SendMessage send a message of the given type to 649 // the other client. Can pass either a set of elements or an 650 // "action", which must have a WriteSessionAction method to go along 651 // with it. Sending with an action supports sending a "hybrid" 652 // message. Sending with elements must be sent as Jingle or Gingle. 653 654 // When passing elems, must be either Jingle or Gingle protocol. 655 // Takes ownership of action_elems. 656 bool SendMessage(ActionType type, const XmlElements& action_elems, 657 SessionError* error); 658 // Sends a messge, but overrides the remote name. 659 bool SendMessage(ActionType type, const XmlElements& action_elems, 660 const std::string& remote_name, 661 SessionError* error); 662 // When passing an action, may be Hybrid protocol. 663 template <typename Action> 664 bool SendMessage(ActionType type, const Action& action, 665 SessionError* error); 666 667 // Helper methods to write the session message stanza. 668 template <typename Action> 669 bool WriteActionMessage(ActionType type, const Action& action, 670 buzz::XmlElement* stanza, WriteError* error); 671 template <typename Action> 672 bool WriteActionMessage(SignalingProtocol protocol, 673 ActionType type, const Action& action, 674 buzz::XmlElement* stanza, WriteError* error); 675 676 // Sending messages in hybrid form requires being able to write them 677 // on a per-protocol basis with a common method signature, which all 678 // of these have. 679 bool WriteSessionAction(SignalingProtocol protocol, 680 const SessionInitiate& init, 681 XmlElements* elems, WriteError* error); 682 bool WriteSessionAction(SignalingProtocol protocol, 683 const TransportInfo& tinfo, 684 XmlElements* elems, WriteError* error); 685 bool WriteSessionAction(SignalingProtocol protocol, 686 const SessionTerminate& term, 687 XmlElements* elems, WriteError* error); 688 689 // Sends a message back to the other client indicating that we have received 690 // and accepted their message. 691 void SendAcknowledgementMessage(const buzz::XmlElement* stanza); 692 693 // Once signaling is ready, the session will use this signal to request the 694 // sending of each message. When messages are received by the other client, 695 // they should be handed to OnIncomingMessage. 696 // (These are called only by SessionManager.) 697 sigslot::signal2<Session* , const buzz::XmlElement*> SignalOutgoingMessage; 698 void OnIncomingMessage(const SessionMessage& msg); 699 700 void OnIncomingResponse(const buzz::XmlElement* orig_stanza, 701 const buzz::XmlElement* response_stanza, 702 const SessionMessage& msg); 703 void OnInitiateAcked(); 704 void OnFailedSend(const buzz::XmlElement* orig_stanza, 705 const buzz::XmlElement* error_stanza); 706 707 // Invoked when an error is found in an incoming message. This is translated 708 // into the appropriate XMPP response by SessionManager. 709 sigslot::signal6<BaseSession*, 710 const buzz::XmlElement*, 711 const buzz::QName&, 712 const std::string&, 713 const std::string&, 714 const buzz::XmlElement*> SignalErrorMessage; 715 716 // Handlers for the various types of messages. These functions may take 717 // pointers to the whole stanza or to just the session element. 718 bool OnInitiateMessage(const SessionMessage& msg, MessageError* error); 719 bool OnAcceptMessage(const SessionMessage& msg, MessageError* error); 720 bool OnRejectMessage(const SessionMessage& msg, MessageError* error); 721 bool OnInfoMessage(const SessionMessage& msg); 722 bool OnTerminateMessage(const SessionMessage& msg, MessageError* error); 723 bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error); 724 bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error); 725 bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error); 726 bool OnRedirectError(const SessionRedirect& redirect, SessionError* error); 727 728 // Verifies that we are in the appropriate state to receive this message. 729 bool CheckState(State state, MessageError* error); 730 731 SessionManager* session_manager_; 732 bool initiate_acked_; 733 std::string local_name_; 734 std::string initiator_name_; 735 std::string remote_name_; 736 SessionClient* client_; 737 TransportParser* transport_parser_; 738 // Keeps track of what protocol we are speaking. 739 SignalingProtocol current_protocol_; 740 741 friend class SessionManager; // For access to constructor, destructor, 742 // and signaling related methods. 743 }; 744 745 } // namespace cricket 746 747 #endif // TALK_P2P_BASE_SESSION_H_ 748