- add third_party src.
[platform/framework/web/crosswalk.git] / src / third_party / libjingle / source / talk / p2p / base / session.h
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   bool SendDescriptionInfoMessage(const ContentInfos& contents);
589   sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage;
590
591  private:
592   // Creates or destroys a session.  (These are called only SessionManager.)
593   Session(SessionManager *session_manager,
594           const std::string& local_name, const std::string& initiator_name,
595           const std::string& sid, const std::string& content_type,
596           SessionClient* client);
597   ~Session();
598   // For each transport info, create a transport proxy.  Can fail for
599   // incompatible transport types.
600   bool CreateTransportProxies(const TransportInfos& tinfos,
601                               SessionError* error);
602   bool OnRemoteCandidates(const TransportInfos& tinfos,
603                           ParseError* error);
604   // Returns a TransportInfo without candidates for each content name.
605   // Uses the transport_type_ of the session.
606   TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const;
607
608     // Maps passed to serialization functions.
609   TransportParserMap GetTransportParsers();
610   ContentParserMap GetContentParsers();
611   CandidateTranslatorMap GetCandidateTranslators();
612
613   virtual void OnTransportRequestSignaling(Transport* transport);
614   virtual void OnTransportConnecting(Transport* transport);
615   virtual void OnTransportWritable(Transport* transport);
616   virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy,
617                                                const Candidates& candidates);
618   virtual void OnTransportSendError(Transport* transport,
619                                     const buzz::XmlElement* stanza,
620                                     const buzz::QName& name,
621                                     const std::string& type,
622                                     const std::string& text,
623                                     const buzz::XmlElement* extra_info);
624   virtual void OnMessage(talk_base::Message *pmsg);
625
626   // Send various kinds of session messages.
627   bool SendInitiateMessage(const SessionDescription* sdesc,
628                            SessionError* error);
629   bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error);
630   bool SendRejectMessage(const std::string& reason, SessionError* error);
631   bool SendTerminateMessage(const std::string& reason, SessionError* error);
632   bool SendTransportInfoMessage(const TransportInfo& tinfo,
633                                 SessionError* error);
634   bool SendTransportInfoMessage(const TransportProxy* transproxy,
635                                 const Candidates& candidates,
636                                 SessionError* error);
637
638   bool ResendAllTransportInfoMessages(SessionError* error);
639   bool SendAllUnsentTransportInfoMessages(SessionError* error);
640
641   // Both versions of SendMessage send a message of the given type to
642   // the other client.  Can pass either a set of elements or an
643   // "action", which must have a WriteSessionAction method to go along
644   // with it.  Sending with an action supports sending a "hybrid"
645   // message.  Sending with elements must be sent as Jingle or Gingle.
646
647   // When passing elems, must be either Jingle or Gingle protocol.
648   // Takes ownership of action_elems.
649   bool SendMessage(ActionType type, const XmlElements& action_elems,
650                    SessionError* error);
651   // When passing an action, may be Hybrid protocol.
652   template <typename Action>
653   bool SendMessage(ActionType type, const Action& action,
654                    SessionError* error);
655
656   // Helper methods to write the session message stanza.
657   template <typename Action>
658   bool WriteActionMessage(ActionType type, const Action& action,
659                           buzz::XmlElement* stanza, WriteError* error);
660   template <typename Action>
661   bool WriteActionMessage(SignalingProtocol protocol,
662                           ActionType type, const Action& action,
663                           buzz::XmlElement* stanza, WriteError* error);
664
665   // Sending messages in hybrid form requires being able to write them
666   // on a per-protocol basis with a common method signature, which all
667   // of these have.
668   bool WriteSessionAction(SignalingProtocol protocol,
669                           const SessionInitiate& init,
670                           XmlElements* elems, WriteError* error);
671   bool WriteSessionAction(SignalingProtocol protocol,
672                           const TransportInfo& tinfo,
673                           XmlElements* elems, WriteError* error);
674   bool WriteSessionAction(SignalingProtocol protocol,
675                           const SessionTerminate& term,
676                           XmlElements* elems, WriteError* error);
677
678   // Sends a message back to the other client indicating that we have received
679   // and accepted their message.
680   void SendAcknowledgementMessage(const buzz::XmlElement* stanza);
681
682   // Once signaling is ready, the session will use this signal to request the
683   // sending of each message.  When messages are received by the other client,
684   // they should be handed to OnIncomingMessage.
685   // (These are called only by SessionManager.)
686   sigslot::signal2<Session* , const buzz::XmlElement*> SignalOutgoingMessage;
687   void OnIncomingMessage(const SessionMessage& msg);
688
689   void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
690                           const buzz::XmlElement* response_stanza,
691                           const SessionMessage& msg);
692   void OnInitiateAcked();
693   void OnFailedSend(const buzz::XmlElement* orig_stanza,
694                     const buzz::XmlElement* error_stanza);
695
696   // Invoked when an error is found in an incoming message.  This is translated
697   // into the appropriate XMPP response by SessionManager.
698   sigslot::signal6<BaseSession*,
699                    const buzz::XmlElement*,
700                    const buzz::QName&,
701                    const std::string&,
702                    const std::string&,
703                    const buzz::XmlElement*> SignalErrorMessage;
704
705   // Handlers for the various types of messages.  These functions may take
706   // pointers to the whole stanza or to just the session element.
707   bool OnInitiateMessage(const SessionMessage& msg, MessageError* error);
708   bool OnAcceptMessage(const SessionMessage& msg, MessageError* error);
709   bool OnRejectMessage(const SessionMessage& msg, MessageError* error);
710   bool OnInfoMessage(const SessionMessage& msg);
711   bool OnTerminateMessage(const SessionMessage& msg, MessageError* error);
712   bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error);
713   bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error);
714   bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error);
715   bool OnRedirectError(const SessionRedirect& redirect, SessionError* error);
716
717   // Verifies that we are in the appropriate state to receive this message.
718   bool CheckState(State state, MessageError* error);
719
720   SessionManager* session_manager_;
721   bool initiate_acked_;
722   std::string local_name_;
723   std::string initiator_name_;
724   std::string remote_name_;
725   SessionClient* client_;
726   TransportParser* transport_parser_;
727   // Keeps track of what protocol we are speaking.
728   SignalingProtocol current_protocol_;
729
730   friend class SessionManager;  // For access to constructor, destructor,
731                                 // and signaling related methods.
732 };
733
734 }  // namespace cricket
735
736 #endif  // TALK_P2P_BASE_SESSION_H_