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