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/base/refcount.h" 37 #include "talk/base/scoped_ptr.h" 38 #include "talk/base/scoped_ref_ptr.h" 39 #include "talk/base/socketaddress.h" 40 #include "talk/p2p/base/parsing.h" 41 #include "talk/p2p/base/port.h" 42 #include "talk/p2p/base/sessionclient.h" 43 #include "talk/p2p/base/sessionmanager.h" 44 #include "talk/p2p/base/sessionmessages.h" 45 #include "talk/p2p/base/transport.h" 46 #include "talk/xmllite/xmlelement.h" 47 #include "talk/xmpp/constants.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 talk_base::RefCountedObject<talk_base::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 68 MessageError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {} 69 70 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: 93 TransportProxy( 94 talk_base::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 113 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*? 116 Transport* impl() const { return transport_->get(); } 117 118 std::string type() const; 119 bool negotiated() const { return negotiated_; } 120 const Candidates& sent_candidates() const { return sent_candidates_; } 121 const Candidates& unsent_candidates() const { return unsent_candidates_; } 122 bool candidates_allocated() const { return candidates_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); 135 void ClearSentCandidates() { sent_candidates_.clear(); } 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(talk_base::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. 165 void OnTransportCandidatesReady(cricket::Transport* transport, 166 const Candidates& candidates) { 167 SignalCandidatesReady(this, candidates); 168 } 169 170 bool local_description_set() const { 171 return local_description_set_; 172 } 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 talk_base::Thread* worker_thread_; 199 std::string sid_; 200 std::string content_name_; 201 talk_base::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 talk_base::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(talk_base::Thread* signaling_thread, 271 talk_base::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 talk_base::Thread* signaling_thread() { return signaling_thread_; } 279 talk_base::Thread* worker_thread() { return worker_thread_; } 280 PortAllocator* port_allocator() { return port_allocator_; } 281 282 // The ID of this session. 283 const std::string& id() const { return sid_; } 284 285 // TODO(juberti): This data is largely redundant, as it can now be obtained 286 // from local/remote_description(). Remove these functions and members. 287 // Returns the XML namespace identifying the type of this session. 288 const std::string& content_type() const { return content_type_; } 289 // Returns the XML namespace identifying the transport used for this session. 290 const std::string& transport_type() const { return transport_type_; } 291 292 // Indicates whether we initiated this session. 293 bool initiator() const { return initiator_; } 294 295 // Returns the application-level description given by our client. 296 // If we are the recipient, this will be NULL until we send an accept. 297 const SessionDescription* local_description() const { 298 return local_description_; 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 return remote_description_; 304 } 305 SessionDescription* remote_description() { 306 return remote_description_; 307 } 308 309 // Takes ownership of SessionDescription* 310 bool set_local_description(const SessionDescription* sdesc) { 311 if (sdesc != local_description_) { 312 delete local_description_; 313 local_description_ = sdesc; 314 } 315 return true; 316 } 317 318 // Takes ownership of SessionDescription* 319 bool set_remote_description(SessionDescription* sdesc) { 320 if (sdesc != remote_description_) { 321 delete remote_description_; 322 remote_description_ = sdesc; 323 } 324 return true; 325 } 326 327 const SessionDescription* initiator_description() const { 328 if (initiator_) { 329 return local_description_; 330 } else { 331 return remote_description_; 332 } 333 } 334 335 // Returns the current state of the session. See the enum above for details. 336 // Each time the state changes, we will fire this signal. 337 State state() const { return state_; } 338 sigslot::signal2<BaseSession* , State> SignalState; 339 340 // Returns the last error in the session. See the enum above for details. 341 // Each time the an error occurs, we will fire this signal. 342 Error error() const { return error_; } 343 const std::string& error_desc() const { return error_desc_; } 344 sigslot::signal2<BaseSession* , Error> SignalError; 345 346 // Updates the state, signaling if necessary. 347 virtual void SetState(State state); 348 349 // Updates the error state, signaling if necessary. 350 // TODO(ronghuawu): remove the SetError method that doesn't take |error_desc|. 351 virtual void SetError(Error error, const std::string& error_desc); 352 353 // Fired when the remote description is updated, with the updated 354 // contents. 355 sigslot::signal2<BaseSession* , const ContentInfos&> 356 SignalRemoteDescriptionUpdate; 357 358 // Fired when SetState is called (regardless if there's a state change), which 359 // indicates the session description might have be updated. 360 sigslot::signal2<BaseSession*, ContentAction> SignalNewLocalDescription; 361 362 // Fired when SetState is called (regardless if there's a state change), which 363 // indicates the session description might have be updated. 364 sigslot::signal2<BaseSession*, ContentAction> SignalNewRemoteDescription; 365 366 // Returns the transport that has been negotiated or NULL if 367 // negotiation is still in progress. 368 virtual Transport* GetTransport(const std::string& content_name); 369 370 // Creates a new channel with the given names. This method may be called 371 // immediately after creating the session. However, the actual 372 // implementation may not be fixed until transport negotiation completes. 373 // This will usually be called from the worker thread, but that 374 // shouldn't be an issue since the main thread will be blocked in 375 // Send when doing so. 376 virtual TransportChannel* CreateChannel(const std::string& content_name, 377 const std::string& channel_name, 378 int component); 379 380 // Returns the channel with the given names. 381 virtual TransportChannel* GetChannel(const std::string& content_name, 382 int component); 383 384 // Destroys the channel with the given names. 385 // This will usually be called from the worker thread, but that 386 // shouldn't be an issue since the main thread will be blocked in 387 // Send when doing so. 388 virtual void DestroyChannel(const std::string& content_name, 389 int component); 390 391 // Returns stats for all channels of all transports. 392 // This avoids exposing the internal structures used to track them. 393 virtual bool GetStats(SessionStats* stats); 394 395 talk_base::SSLIdentity* identity() { return identity_; } 396 397 protected: 398 // Specifies the identity to use in this session. 399 bool SetIdentity(talk_base::SSLIdentity* identity); 400 401 bool PushdownTransportDescription(ContentSource source, 402 ContentAction action, 403 std::string* error_desc); 404 void set_initiator(bool initiator) { initiator_ = initiator; } 405 406 const TransportMap& transport_proxies() const { return transports_; } 407 // Get a TransportProxy by content_name or transport. NULL if not found. 408 TransportProxy* GetTransportProxy(const std::string& content_name); 409 TransportProxy* GetTransportProxy(const Transport* transport); 410 TransportProxy* GetFirstTransportProxy(); 411 void DestroyTransportProxy(const std::string& content_name); 412 // TransportProxy is owned by session. Return proxy just for convenience. 413 TransportProxy* GetOrCreateTransportProxy(const std::string& content_name); 414 // Creates the actual transport object. Overridable for testing. 415 virtual Transport* CreateTransport(const std::string& content_name); 416 417 void OnSignalingReady(); 418 void SpeculativelyConnectAllTransportChannels(); 419 // Helper method to provide remote candidates to the transport. 420 bool OnRemoteCandidates(const std::string& content_name, 421 const Candidates& candidates, 422 std::string* error); 423 424 // This method will mux transport channels by content_name. 425 // First content is used for muxing. 426 bool MaybeEnableMuxingSupport(); 427 428 // Called when a transport requests signaling. 429 virtual void OnTransportRequestSignaling(Transport* transport) { 430 } 431 432 // Called when the first channel of a transport begins connecting. We use 433 // this to start a timer, to make sure that the connection completes in a 434 // reasonable amount of time. 435 virtual void OnTransportConnecting(Transport* transport) { 436 } 437 438 // Called when a transport changes its writable state. We track this to make 439 // sure that the transport becomes writable within a reasonable amount of 440 // time. If this does not occur, we signal an error. 441 virtual void OnTransportWritable(Transport* transport) { 442 } 443 virtual void OnTransportReadable(Transport* transport) { 444 } 445 446 // Called when a transport has found its steady-state connections. 447 virtual void OnTransportCompleted(Transport* transport) { 448 } 449 450 // Called when a transport has failed permanently. 451 virtual void OnTransportFailed(Transport* transport) { 452 } 453 454 // Called when a transport signals that it has new candidates. 455 virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy, 456 const Candidates& candidates) { 457 } 458 459 // Called when a transport signals that it found an error in an incoming 460 // message. 461 virtual void OnTransportSendError(Transport* transport, 462 const buzz::XmlElement* stanza, 463 const buzz::QName& name, 464 const std::string& type, 465 const std::string& text, 466 const buzz::XmlElement* extra_info) { 467 } 468 469 virtual void OnTransportRouteChange( 470 Transport* transport, 471 int component, 472 const cricket::Candidate& remote_candidate) { 473 } 474 475 virtual void OnTransportCandidatesAllocationDone(Transport* transport); 476 477 // Called when all transport channels allocated required candidates. 478 // This method should be used as an indication of candidates gathering process 479 // is completed and application can now send local candidates list to remote. 480 virtual void OnCandidatesAllocationDone() { 481 } 482 483 // Handles the ice role change callback from Transport. This must be 484 // propagated to all the transports. 485 virtual void OnRoleConflict(); 486 487 // Handles messages posted to us. 488 virtual void OnMessage(talk_base::Message *pmsg); 489 490 protected: 491 State state_; 492 Error error_; 493 std::string error_desc_; 494 495 private: 496 // Helper methods to push local and remote transport descriptions. 497 bool PushdownLocalTransportDescription( 498 const SessionDescription* sdesc, ContentAction action, 499 std::string* error_desc); 500 bool PushdownRemoteTransportDescription( 501 const SessionDescription* sdesc, ContentAction action, 502 std::string* error_desc); 503 504 bool IsCandidateAllocationDone() const; 505 void MaybeCandidateAllocationDone(); 506 507 // This method will delete the Transport and TransportChannelImpls and 508 // replace those with the selected Transport objects. Selection is done 509 // based on the content_name and in this case first MediaContent information 510 // is used for mux. 511 bool SetSelectedProxy(const std::string& content_name, 512 const ContentGroup* muxed_group); 513 // Log session state. 514 void LogState(State old_state, State new_state); 515 516 // Returns true and the TransportInfo of the given |content_name| 517 // from |description|. Returns false if it's not available. 518 bool GetTransportDescription(const SessionDescription* description, 519 const std::string& content_name, 520 TransportDescription* info); 521 522 // Fires the new description signal according to the current state. 523 void SignalNewDescription(); 524 525 // Gets the ContentAction and ContentSource according to the session state. 526 bool GetContentAction(ContentAction* action, ContentSource* source); 527 528 talk_base::Thread* signaling_thread_; 529 talk_base::Thread* worker_thread_; 530 PortAllocator* port_allocator_; 531 std::string sid_; 532 std::string content_type_; 533 std::string transport_type_; 534 bool initiator_; 535 talk_base::SSLIdentity* identity_; 536 const SessionDescription* local_description_; 537 SessionDescription* remote_description_; 538 uint64 ice_tiebreaker_; 539 // This flag will be set to true after the first role switch. This flag 540 // will enable us to stop any role switch during the call. 541 bool role_switch_; 542 TransportMap transports_; 543 }; 544 545 // A specific Session created by the SessionManager, using XMPP for protocol. 546 class Session : public BaseSession { 547 public: 548 // Returns the manager that created and owns this session. 549 SessionManager* session_manager() const { return session_manager_; } 550 551 // Returns the client that is handling the application data of this session. 552 SessionClient* client() const { return client_; } 553 554 // Returns the JID of this client. 555 const std::string& local_name() const { return local_name_; } 556 557 // Returns the JID of the other peer in this session. 558 const std::string& remote_name() const { return remote_name_; } 559 560 // Set the JID of the other peer in this session. 561 // Typically the remote_name_ is set when the session is initiated. 562 // However, sometimes (e.g when a proxy is used) the peer name is 563 // known after the BaseSession has been initiated and it must be updated 564 // explicitly. 565 void set_remote_name(const std::string& name) { remote_name_ = name; } 566 567 // Set the JID of the initiator of this session. Allows for the overriding 568 // of the initiator to be a third-party, eg. the MUC JID when creating p2p 569 // sessions. 570 void set_initiator_name(const std::string& name) { initiator_name_ = name; } 571 572 // Indicates the JID of the entity who initiated this session. 573 // In special cases, may be different than both local_name and remote_name. 574 const std::string& initiator_name() const { return initiator_name_; } 575 576 SignalingProtocol current_protocol() const { return current_protocol_; } 577 578 void set_current_protocol(SignalingProtocol protocol) { 579 current_protocol_ = protocol; 580 } 581 582 // Updates the error state, signaling if necessary. 583 virtual void SetError(Error error, const std::string& error_desc); 584 585 // When the session needs to send signaling messages, it beings by requesting 586 // signaling. The client should handle this by calling OnSignalingReady once 587 // it is ready to send the messages. 588 // (These are called only by SessionManager.) 589 sigslot::signal1<Session*> SignalRequestSignaling; 590 void OnSignalingReady() { BaseSession::OnSignalingReady(); } 591 592 // Takes ownership of session description. 593 // TODO: Add an error argument to pass back to the caller. 594 bool Initiate(const std::string& to, 595 const SessionDescription* sdesc); 596 597 // When we receive an initiate, we create a session in the 598 // RECEIVEDINITIATE state and respond by accepting or rejecting. 599 // Takes ownership of session description. 600 // TODO: Add an error argument to pass back to the caller. 601 bool Accept(const SessionDescription* sdesc); 602 bool Reject(const std::string& reason); 603 bool Terminate() { 604 return TerminateWithReason(STR_TERMINATE_SUCCESS); 605 } 606 bool TerminateWithReason(const std::string& reason); 607 // Fired whenever we receive a terminate message along with a reason 608 sigslot::signal2<Session*, const std::string&> SignalReceivedTerminateReason; 609 610 // The two clients in the session may also send one another 611 // arbitrary XML messages, which are called "info" messages. Sending 612 // takes ownership of the given elements. The signal does not; the 613 // parent element will be deleted after the signal. 614 bool SendInfoMessage(const XmlElements& elems, 615 const std::string& remote_name); 616 bool SendDescriptionInfoMessage(const ContentInfos& contents); 617 sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage; 618 619 private: 620 // Creates or destroys a session. (These are called only SessionManager.) 621 Session(SessionManager *session_manager, 622 const std::string& local_name, const std::string& initiator_name, 623 const std::string& sid, const std::string& content_type, 624 SessionClient* client); 625 ~Session(); 626 // For each transport info, create a transport proxy. Can fail for 627 // incompatible transport types. 628 bool CreateTransportProxies(const TransportInfos& tinfos, 629 SessionError* error); 630 bool OnRemoteCandidates(const TransportInfos& tinfos, 631 ParseError* error); 632 // Returns a TransportInfo without candidates for each content name. 633 // Uses the transport_type_ of the session. 634 TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const; 635 636 // Maps passed to serialization functions. 637 TransportParserMap GetTransportParsers(); 638 ContentParserMap GetContentParsers(); 639 CandidateTranslatorMap GetCandidateTranslators(); 640 641 virtual void OnTransportRequestSignaling(Transport* transport); 642 virtual void OnTransportConnecting(Transport* transport); 643 virtual void OnTransportWritable(Transport* transport); 644 virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy, 645 const Candidates& candidates); 646 virtual void OnTransportSendError(Transport* transport, 647 const buzz::XmlElement* stanza, 648 const buzz::QName& name, 649 const std::string& type, 650 const std::string& text, 651 const buzz::XmlElement* extra_info); 652 virtual void OnMessage(talk_base::Message *pmsg); 653 654 // Send various kinds of session messages. 655 bool SendInitiateMessage(const SessionDescription* sdesc, 656 SessionError* error); 657 bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error); 658 bool SendRejectMessage(const std::string& reason, SessionError* error); 659 bool SendTerminateMessage(const std::string& reason, SessionError* error); 660 bool SendTransportInfoMessage(const TransportInfo& tinfo, 661 SessionError* error); 662 bool SendTransportInfoMessage(const TransportProxy* transproxy, 663 const Candidates& candidates, 664 SessionError* error); 665 666 bool ResendAllTransportInfoMessages(SessionError* error); 667 bool SendAllUnsentTransportInfoMessages(SessionError* error); 668 669 // All versions of SendMessage send a message of the given type to 670 // the other client. Can pass either a set of elements or an 671 // "action", which must have a WriteSessionAction method to go along 672 // with it. Sending with an action supports sending a "hybrid" 673 // message. Sending with elements must be sent as Jingle or Gingle. 674 675 // When passing elems, must be either Jingle or Gingle protocol. 676 // Takes ownership of action_elems. 677 bool SendMessage(ActionType type, const XmlElements& action_elems, 678 SessionError* error); 679 // Sends a messge, but overrides the remote name. 680 bool SendMessage(ActionType type, const XmlElements& action_elems, 681 const std::string& remote_name, 682 SessionError* error); 683 // When passing an action, may be Hybrid protocol. 684 template <typename Action> 685 bool SendMessage(ActionType type, const Action& action, 686 SessionError* error); 687 688 // Helper methods to write the session message stanza. 689 template <typename Action> 690 bool WriteActionMessage(ActionType type, const Action& action, 691 buzz::XmlElement* stanza, WriteError* error); 692 template <typename Action> 693 bool WriteActionMessage(SignalingProtocol protocol, 694 ActionType type, const Action& action, 695 buzz::XmlElement* stanza, WriteError* error); 696 697 // Sending messages in hybrid form requires being able to write them 698 // on a per-protocol basis with a common method signature, which all 699 // of these have. 700 bool WriteSessionAction(SignalingProtocol protocol, 701 const SessionInitiate& init, 702 XmlElements* elems, WriteError* error); 703 bool WriteSessionAction(SignalingProtocol protocol, 704 const TransportInfo& tinfo, 705 XmlElements* elems, WriteError* error); 706 bool WriteSessionAction(SignalingProtocol protocol, 707 const SessionTerminate& term, 708 XmlElements* elems, WriteError* error); 709 710 // Sends a message back to the other client indicating that we have received 711 // and accepted their message. 712 void SendAcknowledgementMessage(const buzz::XmlElement* stanza); 713 714 // Once signaling is ready, the session will use this signal to request the 715 // sending of each message. When messages are received by the other client, 716 // they should be handed to OnIncomingMessage. 717 // (These are called only by SessionManager.) 718 sigslot::signal2<Session* , const buzz::XmlElement*> SignalOutgoingMessage; 719 void OnIncomingMessage(const SessionMessage& msg); 720 721 void OnIncomingResponse(const buzz::XmlElement* orig_stanza, 722 const buzz::XmlElement* response_stanza, 723 const SessionMessage& msg); 724 void OnInitiateAcked(); 725 void OnFailedSend(const buzz::XmlElement* orig_stanza, 726 const buzz::XmlElement* error_stanza); 727 728 // Invoked when an error is found in an incoming message. This is translated 729 // into the appropriate XMPP response by SessionManager. 730 sigslot::signal6<BaseSession*, 731 const buzz::XmlElement*, 732 const buzz::QName&, 733 const std::string&, 734 const std::string&, 735 const buzz::XmlElement*> SignalErrorMessage; 736 737 // Handlers for the various types of messages. These functions may take 738 // pointers to the whole stanza or to just the session element. 739 bool OnInitiateMessage(const SessionMessage& msg, MessageError* error); 740 bool OnAcceptMessage(const SessionMessage& msg, MessageError* error); 741 bool OnRejectMessage(const SessionMessage& msg, MessageError* error); 742 bool OnInfoMessage(const SessionMessage& msg); 743 bool OnTerminateMessage(const SessionMessage& msg, MessageError* error); 744 bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error); 745 bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error); 746 bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error); 747 bool OnRedirectError(const SessionRedirect& redirect, SessionError* error); 748 749 // Verifies that we are in the appropriate state to receive this message. 750 bool CheckState(State state, MessageError* error); 751 752 SessionManager* session_manager_; 753 bool initiate_acked_; 754 std::string local_name_; 755 std::string initiator_name_; 756 std::string remote_name_; 757 SessionClient* client_; 758 TransportParser* transport_parser_; 759 // Keeps track of what protocol we are speaking. 760 SignalingProtocol current_protocol_; 761 762 friend class SessionManager; // For access to constructor, destructor, 763 // and signaling related methods. 764 }; 765 766 } // namespace cricket 767 768 #endif // TALK_P2P_BASE_SESSION_H_ 769