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