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