3 * Copyright 2004--2005, Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
28 #ifndef TALK_P2P_BASE_SESSION_H_
29 #define TALK_P2P_BASE_SESSION_H_
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 "talk/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"
52 class P2PTransportChannel;
54 class TransportChannel;
55 class TransportChannelProxy;
56 class TransportChannelImpl;
58 typedef rtc::RefCountedObject<rtc::scoped_ptr<Transport> >
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 {
67 // if unset, assume type is a parse error
68 MessageError() : ParseError(), type(buzz::QN_STANZA_BAD_REQUEST) {}
70 void SetType(const buzz::QName type) {
75 // Used for errors that may be returned by public session methods that
77 // TODO: Use this error in Session::Initiate and
79 struct SessionError : WriteError {
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.
88 typedef std::map<int, TransportChannelProxy*> ChannelMap;
90 class TransportProxy : public sigslot::has_slots<>,
91 public CandidateTranslator {
94 rtc::Thread* worker_thread,
95 const std::string& sid,
96 const std::string& content_name,
97 TransportWrapper* transport)
98 : worker_thread_(worker_thread),
100 content_name_(content_name),
101 transport_(transport),
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);
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*?
116 Transport* impl() const { return transport_->get(); }
118 const 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;
127 TransportChannel* GetChannel(int component);
128 TransportChannel* CreateChannel(const std::string& channel_name,
130 bool HasChannel(int component);
131 void DestroyChannel(int component);
133 void AddSentCandidates(const Candidates& candidates);
134 void AddUnsentCandidates(const Candidates& candidates);
135 void ClearSentCandidates() { sent_candidates_.clear(); }
136 void ClearUnsentCandidates() { unsent_candidates_.clear(); }
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();
143 // Mux this proxy onto the specified proxy's transport.
144 bool SetupMux(TransportProxy* proxy);
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);
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;
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);
170 bool local_description_set() const {
171 return local_description_set_;
173 bool remote_description_set() const {
174 return remote_description_set_;
177 // Handles sending of ready candidates and receiving of remote candidates.
178 sigslot::signal2<TransportProxy*,
179 const std::vector<Candidate>&> SignalCandidatesReady;
182 TransportChannelProxy* GetChannelProxy(int component) const;
183 TransportChannelProxy* GetChannelProxyByName(const std::string& name) const;
185 TransportChannelImpl* GetOrCreateChannelProxyImpl(int component);
186 TransportChannelImpl* GetOrCreateChannelProxyImpl_w(int component);
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);
198 rtc::Thread* const worker_thread_;
199 const std::string sid_;
200 const std::string content_name_;
201 rtc::scoped_refptr<TransportWrapper> transport_;
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_;
212 typedef std::map<std::string, TransportProxy*> TransportMap;
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;
218 struct SessionStats {
219 ProxyTransportMap proxy_to_transport;
220 TransportStatsMap transport_stats;
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 {
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
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
267 // Convert State to a readable string.
268 static std::string StateToString(State state);
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,
276 virtual ~BaseSession();
278 // These are const to allow them to be called from const methods.
279 rtc::Thread* signaling_thread() const { return signaling_thread_; }
280 rtc::Thread* worker_thread() const { return worker_thread_; }
281 PortAllocator* port_allocator() const { return port_allocator_; }
283 // The ID of this session.
284 const std::string& id() const { return sid_; }
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.
289 const std::string& content_type() const { return content_type_; }
290 // Returns the XML namespace identifying the transport used for this session.
291 const std::string& transport_type() const { return transport_type_; }
293 // Indicates whether we initiated this session.
294 bool initiator() const { return initiator_; }
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;
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;
304 SessionDescription* remote_description();
306 // Takes ownership of SessionDescription*
307 void set_local_description(const SessionDescription* sdesc);
309 // Takes ownership of SessionDescription*
310 void set_remote_description(SessionDescription* sdesc);
312 const SessionDescription* initiator_description() const;
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.
316 State state() const { return state_; }
317 sigslot::signal2<BaseSession* , State> SignalState;
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.
321 Error error() const { return error_; }
322 const std::string& error_desc() const { return error_desc_; }
323 sigslot::signal2<BaseSession* , Error> SignalError;
325 // Updates the state, signaling if necessary.
326 virtual void SetState(State state);
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);
332 // Fired when the remote description is updated, with the updated
334 sigslot::signal2<BaseSession* , const ContentInfos&>
335 SignalRemoteDescriptionUpdate;
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;
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;
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);
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,
359 // Returns the channel with the given names.
360 virtual TransportChannel* GetChannel(const std::string& content_name,
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,
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);
374 rtc::SSLIdentity* identity() { return identity_; }
377 // Specifies the identity to use in this session.
378 bool SetIdentity(rtc::SSLIdentity* identity);
380 bool PushdownTransportDescription(ContentSource source,
381 ContentAction action,
382 std::string* error_desc);
383 void set_initiator(bool initiator) { initiator_ = initiator; }
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);
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,
403 // This method will mux transport channels by content_name.
404 // First content is used for muxing.
405 bool MaybeEnableMuxingSupport();
407 // Called when a transport requests signaling.
408 virtual void OnTransportRequestSignaling(Transport* transport) {
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.
414 virtual void OnTransportConnecting(Transport* transport) {
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.
420 virtual void OnTransportWritable(Transport* transport) {
422 virtual void OnTransportReadable(Transport* transport) {
425 // Called when a transport has found its steady-state connections.
426 virtual void OnTransportCompleted(Transport* transport) {
429 // Called when a transport has failed permanently.
430 virtual void OnTransportFailed(Transport* transport) {
433 // Called when a transport signals that it has new candidates.
434 virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy,
435 const Candidates& candidates) {
438 // Called when a transport signals that it found an error in an incoming
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) {
448 virtual void OnTransportRouteChange(
449 Transport* transport,
451 const cricket::Candidate& remote_candidate) {
454 virtual void OnTransportCandidatesAllocationDone(Transport* transport);
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.
459 virtual void OnCandidatesAllocationDone() {
462 // Handles the ice role change callback from Transport. This must be
463 // propagated to all the transports.
464 virtual void OnRoleConflict();
466 // Handles messages posted to us.
467 virtual void OnMessage(rtc::Message *pmsg);
472 std::string error_desc_;
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);
483 bool IsCandidateAllocationDone() const;
484 void MaybeCandidateAllocationDone();
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
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);
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);
501 // Fires the new description signal according to the current state.
502 void SignalNewDescription();
504 // Gets the ContentAction and ContentSource according to the session state.
505 bool GetContentAction(ContentAction* action, ContentSource* source);
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_;
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.
521 TransportMap transports_;
524 // A specific Session created by the SessionManager, using XMPP for protocol.
525 class Session : public BaseSession {
527 // Returns the manager that created and owns this session.
528 SessionManager* session_manager() const { return session_manager_; }
530 // Returns the client that is handling the application data of this session.
531 SessionClient* client() const { return client_; }
533 // Returns the JID of this client.
534 const std::string& local_name() const { return local_name_; }
536 // Returns the JID of the other peer in this session.
537 const std::string& remote_name() const { return remote_name_; }
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
544 void set_remote_name(const std::string& name) { remote_name_ = name; }
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
549 void set_initiator_name(const std::string& name) { initiator_name_ = name; }
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.
553 const std::string& initiator_name() const { return initiator_name_; }
555 SignalingProtocol current_protocol() const { return current_protocol_; }
557 void set_current_protocol(SignalingProtocol protocol) {
558 current_protocol_ = protocol;
561 // Updates the error state, signaling if necessary.
562 virtual void SetError(Error error, const std::string& error_desc);
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;
569 void OnSignalingReady() { BaseSession::OnSignalingReady(); }
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);
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);
583 return TerminateWithReason(STR_TERMINATE_SUCCESS);
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;
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;
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);
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,
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;
615 // Maps passed to serialization functions.
616 TransportParserMap GetTransportParsers();
617 ContentParserMap GetContentParsers();
618 CandidateTranslatorMap GetCandidateTranslators();
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);
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);
645 bool ResendAllTransportInfoMessages(SessionError* error);
646 bool SendAllUnsentTransportInfoMessages(SessionError* error);
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.
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);
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);
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
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);
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);
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);
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);
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*,
714 const buzz::XmlElement*> SignalErrorMessage;
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);
728 // Verifies that we are in the appropriate state to receive this message.
729 bool CheckState(State state, MessageError* error);
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_;
741 friend class SessionManager; // For access to constructor, destructor,
742 // and signaling related methods.
745 } // namespace cricket
747 #endif // TALK_P2P_BASE_SESSION_H_