blob: af34240654dc650f4ecb7666311c93cf1b5b87b3 [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);
wu@webrtc.org91053e72013-08-10 07:18:04 +0000144 void SetIdentity(talk_base::SSLIdentity* identity);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145 bool SetLocalTransportDescription(const TransportDescription& description,
146 ContentAction action);
147 bool SetRemoteTransportDescription(const TransportDescription& description,
148 ContentAction action);
149 void OnSignalingReady();
150 bool OnRemoteCandidates(const Candidates& candidates, std::string* error);
151
152 // CandidateTranslator methods.
153 virtual bool GetChannelNameFromComponent(
154 int component, std::string* channel_name) const;
155 virtual bool GetComponentFromChannelName(
156 const std::string& channel_name, int* component) const;
157
158 // Called when a transport signals that it has new candidates.
159 void OnTransportCandidatesReady(cricket::Transport* transport,
160 const Candidates& candidates) {
161 SignalCandidatesReady(this, candidates);
162 }
163
164 // Handles sending of ready candidates and receiving of remote candidates.
165 sigslot::signal2<TransportProxy*,
166 const std::vector<Candidate>&> SignalCandidatesReady;
167
168 private:
169 TransportChannelProxy* GetChannelProxy(int component) const;
170 TransportChannelProxy* GetChannelProxyByName(const std::string& name) const;
171 void ReplaceChannelProxyImpl(TransportChannelProxy* channel_proxy,
172 size_t index);
173 TransportChannelImpl* GetOrCreateChannelProxyImpl(int component);
174 void SetChannelProxyImpl(int component,
175 TransportChannelProxy* proxy);
176
177 std::string sid_;
178 std::string content_name_;
179 talk_base::scoped_refptr<TransportWrapper> transport_;
180 bool connecting_;
181 bool negotiated_;
182 ChannelMap channels_;
183 Candidates sent_candidates_;
184 Candidates unsent_candidates_;
185 bool candidates_allocated_;
186};
187
188typedef std::map<std::string, TransportProxy*> TransportMap;
189
190// Statistics for all the transports of this session.
191typedef std::map<std::string, TransportStats> TransportStatsMap;
192typedef std::map<std::string, std::string> ProxyTransportMap;
193
194struct SessionStats {
195 ProxyTransportMap proxy_to_transport;
196 TransportStatsMap transport_stats;
197};
198
199// A BaseSession manages general session state. This includes negotiation
200// of both the application-level and network-level protocols: the former
201// defines what will be sent and the latter defines how it will be sent. Each
202// network-level protocol is represented by a Transport object. Each Transport
203// participates in the network-level negotiation. The individual streams of
204// packets are represented by TransportChannels. The application-level protocol
205// is represented by SessionDecription objects.
206class BaseSession : public sigslot::has_slots<>,
207 public talk_base::MessageHandler {
208 public:
209 enum {
210 MSG_TIMEOUT = 0,
211 MSG_ERROR,
212 MSG_STATE,
213 };
214
215 enum State {
216 STATE_INIT = 0,
217 STATE_SENTINITIATE, // sent initiate, waiting for Accept or Reject
218 STATE_RECEIVEDINITIATE, // received an initiate. Call Accept or Reject
219 STATE_SENTPRACCEPT, // sent provisional Accept
220 STATE_SENTACCEPT, // sent accept. begin connecting transport
221 STATE_RECEIVEDPRACCEPT, // received provisional Accept, waiting for Accept
222 STATE_RECEIVEDACCEPT, // received accept. begin connecting transport
223 STATE_SENTMODIFY, // sent modify, waiting for Accept or Reject
224 STATE_RECEIVEDMODIFY, // received modify, call Accept or Reject
225 STATE_SENTREJECT, // sent reject after receiving initiate
226 STATE_RECEIVEDREJECT, // received reject after sending initiate
227 STATE_SENTREDIRECT, // sent direct after receiving initiate
228 STATE_SENTTERMINATE, // sent terminate (any time / either side)
229 STATE_RECEIVEDTERMINATE, // received terminate (any time / either side)
230 STATE_INPROGRESS, // session accepted and in progress
231 STATE_DEINIT, // session is being destroyed
232 };
233
234 enum Error {
235 ERROR_NONE = 0, // no error
236 ERROR_TIME = 1, // no response to signaling
237 ERROR_RESPONSE = 2, // error during signaling
238 ERROR_NETWORK = 3, // network error, could not allocate network resources
239 ERROR_CONTENT = 4, // channel errors in SetLocalContent/SetRemoteContent
240 ERROR_TRANSPORT = 5, // transport error of some kind
241 };
242
243 // Convert State to a readable string.
244 static std::string StateToString(State state);
245
246 BaseSession(talk_base::Thread* signaling_thread,
247 talk_base::Thread* worker_thread,
248 PortAllocator* port_allocator,
249 const std::string& sid,
250 const std::string& content_type,
251 bool initiator);
252 virtual ~BaseSession();
253
254 talk_base::Thread* signaling_thread() { return signaling_thread_; }
255 talk_base::Thread* worker_thread() { return worker_thread_; }
256 PortAllocator* port_allocator() { return port_allocator_; }
257
258 // The ID of this session.
259 const std::string& id() const { return sid_; }
260
261 // TODO(juberti): This data is largely redundant, as it can now be obtained
262 // from local/remote_description(). Remove these functions and members.
263 // Returns the XML namespace identifying the type of this session.
264 const std::string& content_type() const { return content_type_; }
265 // Returns the XML namespace identifying the transport used for this session.
266 const std::string& transport_type() const { return transport_type_; }
267
268 // Indicates whether we initiated this session.
269 bool initiator() const { return initiator_; }
270
271 // Returns the application-level description given by our client.
272 // If we are the recipient, this will be NULL until we send an accept.
273 const SessionDescription* local_description() const {
274 return local_description_;
275 }
276 // Returns the application-level description given by the other client.
277 // If we are the initiator, this will be NULL until we receive an accept.
278 const SessionDescription* remote_description() const {
279 return remote_description_;
280 }
281 SessionDescription* remote_description() {
282 return remote_description_;
283 }
284
285 // Takes ownership of SessionDescription*
286 bool set_local_description(const SessionDescription* sdesc) {
287 if (sdesc != local_description_) {
288 delete local_description_;
289 local_description_ = sdesc;
290 }
291 return true;
292 }
293
294 // Takes ownership of SessionDescription*
295 bool set_remote_description(SessionDescription* sdesc) {
296 if (sdesc != remote_description_) {
297 delete remote_description_;
298 remote_description_ = sdesc;
299 }
300 return true;
301 }
302
303 const SessionDescription* initiator_description() const {
304 if (initiator_) {
305 return local_description_;
306 } else {
307 return remote_description_;
308 }
309 }
310
311 // Returns the current state of the session. See the enum above for details.
312 // Each time the state changes, we will fire this signal.
313 State state() const { return state_; }
314 sigslot::signal2<BaseSession* , State> SignalState;
315
316 // Returns the last error in the session. See the enum above for details.
317 // Each time the an error occurs, we will fire this signal.
318 Error error() const { return error_; }
319 sigslot::signal2<BaseSession* , Error> SignalError;
320
321 // Updates the state, signaling if necessary.
322 virtual void SetState(State state);
323
324 // Updates the error state, signaling if necessary.
325 virtual void SetError(Error error);
326
327 // Fired when the remote description is updated, with the updated
328 // contents.
329 sigslot::signal2<BaseSession* , const ContentInfos&>
330 SignalRemoteDescriptionUpdate;
331
332 // Fired when SetState is called (regardless if there's a state change), which
333 // indicates the session description might have be updated.
334 sigslot::signal2<BaseSession*, ContentAction> SignalNewLocalDescription;
335
336 // Fired when SetState is called (regardless if there's a state change), which
337 // indicates the session description might have be updated.
338 sigslot::signal2<BaseSession*, ContentAction> SignalNewRemoteDescription;
339
340 // Returns the transport that has been negotiated or NULL if
341 // negotiation is still in progress.
342 Transport* GetTransport(const std::string& content_name);
343
344 // Creates a new channel with the given names. This method may be called
345 // immediately after creating the session. However, the actual
346 // implementation may not be fixed until transport negotiation completes.
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 TransportChannel* CreateChannel(const std::string& content_name,
351 const std::string& channel_name,
352 int component);
353
354 // Returns the channel with the given names.
355 virtual TransportChannel* GetChannel(const std::string& content_name,
356 int component);
357
358 // Destroys the channel with the given names.
359 // This will usually be called from the worker thread, but that
360 // shouldn't be an issue since the main thread will be blocked in
361 // Send when doing so.
362 virtual void DestroyChannel(const std::string& content_name,
363 int component);
364
365 // Returns stats for all channels of all transports.
366 // This avoids exposing the internal structures used to track them.
367 virtual bool GetStats(SessionStats* stats);
368
wu@webrtc.org91053e72013-08-10 07:18:04 +0000369 talk_base::SSLIdentity* identity() { return identity_; }
370
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000371 protected:
wu@webrtc.org91053e72013-08-10 07:18:04 +0000372 // Specifies the identity to use in this session.
373 bool SetIdentity(talk_base::SSLIdentity* identity);
374
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000375 bool PushdownTransportDescription(ContentSource source,
376 ContentAction action);
377 void set_initiator(bool initiator) { initiator_ = initiator; }
378
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000379 const TransportMap& transport_proxies() const { return transports_; }
380 // Get a TransportProxy by content_name or transport. NULL if not found.
381 TransportProxy* GetTransportProxy(const std::string& content_name);
382 TransportProxy* GetTransportProxy(const Transport* transport);
383 TransportProxy* GetFirstTransportProxy();
384 void DestroyTransportProxy(const std::string& content_name);
385 // TransportProxy is owned by session. Return proxy just for convenience.
386 TransportProxy* GetOrCreateTransportProxy(const std::string& content_name);
387 // Creates the actual transport object. Overridable for testing.
388 virtual Transport* CreateTransport(const std::string& content_name);
389
390 void OnSignalingReady();
391 void SpeculativelyConnectAllTransportChannels();
392 // Helper method to provide remote candidates to the transport.
393 bool OnRemoteCandidates(const std::string& content_name,
394 const Candidates& candidates,
395 std::string* error);
396
397 // This method will mux transport channels by content_name.
398 // First content is used for muxing.
399 bool MaybeEnableMuxingSupport();
400
401 // Called when a transport requests signaling.
402 virtual void OnTransportRequestSignaling(Transport* transport) {
403 }
404
405 // Called when the first channel of a transport begins connecting. We use
406 // this to start a timer, to make sure that the connection completes in a
407 // reasonable amount of time.
408 virtual void OnTransportConnecting(Transport* transport) {
409 }
410
411 // Called when a transport changes its writable state. We track this to make
412 // sure that the transport becomes writable within a reasonable amount of
413 // time. If this does not occur, we signal an error.
414 virtual void OnTransportWritable(Transport* transport) {
415 }
416 virtual void OnTransportReadable(Transport* transport) {
417 }
418
419 // Called when a transport signals that it has new candidates.
420 virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy,
421 const Candidates& candidates) {
422 }
423
424 // Called when a transport signals that it found an error in an incoming
425 // message.
426 virtual void OnTransportSendError(Transport* transport,
427 const buzz::XmlElement* stanza,
428 const buzz::QName& name,
429 const std::string& type,
430 const std::string& text,
431 const buzz::XmlElement* extra_info) {
432 }
433
434 virtual void OnTransportRouteChange(
435 Transport* transport,
436 int component,
437 const cricket::Candidate& remote_candidate) {
438 }
439
440 virtual void OnTransportCandidatesAllocationDone(Transport* transport);
441
442 // Called when all transport channels allocated required candidates.
443 // This method should be used as an indication of candidates gathering process
444 // is completed and application can now send local candidates list to remote.
445 virtual void OnCandidatesAllocationDone() {
446 }
447
448 // Handles the ice role change callback from Transport. This must be
449 // propagated to all the transports.
450 virtual void OnRoleConflict();
451
452 // Handles messages posted to us.
453 virtual void OnMessage(talk_base::Message *pmsg);
454
455 protected:
456 State state_;
457 Error error_;
458
459 private:
460 // Helper methods to push local and remote transport descriptions.
461 bool PushdownLocalTransportDescription(
462 const SessionDescription* sdesc, ContentAction action);
463 bool PushdownRemoteTransportDescription(
464 const SessionDescription* sdesc, ContentAction action);
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 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 talk_base::Thread* signaling_thread_;
491 talk_base::Thread* worker_thread_;
492 PortAllocator* port_allocator_;
493 std::string sid_;
494 std::string content_type_;
495 std::string transport_type_;
496 bool initiator_;
497 talk_base::SSLIdentity* identity_;
498 const SessionDescription* local_description_;
499 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.
508class 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);
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 bool SendDescriptionInfoMessage(const ContentInfos& contents);
578 sigslot::signal2<Session*, const buzz::XmlElement*> SignalInfoMessage;
579
580 private:
581 // Creates or destroys a session. (These are called only SessionManager.)
582 Session(SessionManager *session_manager,
583 const std::string& local_name, const std::string& initiator_name,
584 const std::string& sid, const std::string& content_type,
585 SessionClient* client);
586 ~Session();
587 // For each transport info, create a transport proxy. Can fail for
588 // incompatible transport types.
589 bool CreateTransportProxies(const TransportInfos& tinfos,
590 SessionError* error);
591 bool OnRemoteCandidates(const TransportInfos& tinfos,
592 ParseError* error);
593 // Returns a TransportInfo without candidates for each content name.
594 // Uses the transport_type_ of the session.
595 TransportInfos GetEmptyTransportInfos(const ContentInfos& contents) const;
596
597 // Maps passed to serialization functions.
598 TransportParserMap GetTransportParsers();
599 ContentParserMap GetContentParsers();
600 CandidateTranslatorMap GetCandidateTranslators();
601
602 virtual void OnTransportRequestSignaling(Transport* transport);
603 virtual void OnTransportConnecting(Transport* transport);
604 virtual void OnTransportWritable(Transport* transport);
605 virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy,
606 const Candidates& candidates);
607 virtual void OnTransportSendError(Transport* transport,
608 const buzz::XmlElement* stanza,
609 const buzz::QName& name,
610 const std::string& type,
611 const std::string& text,
612 const buzz::XmlElement* extra_info);
613 virtual void OnMessage(talk_base::Message *pmsg);
614
615 // Send various kinds of session messages.
616 bool SendInitiateMessage(const SessionDescription* sdesc,
617 SessionError* error);
618 bool SendAcceptMessage(const SessionDescription* sdesc, SessionError* error);
619 bool SendRejectMessage(const std::string& reason, SessionError* error);
620 bool SendTerminateMessage(const std::string& reason, SessionError* error);
621 bool SendTransportInfoMessage(const TransportInfo& tinfo,
622 SessionError* error);
623 bool SendTransportInfoMessage(const TransportProxy* transproxy,
624 const Candidates& candidates,
625 SessionError* error);
626
627 bool ResendAllTransportInfoMessages(SessionError* error);
628 bool SendAllUnsentTransportInfoMessages(SessionError* error);
629
630 // Both versions of SendMessage send a message of the given type to
631 // the other client. Can pass either a set of elements or an
632 // "action", which must have a WriteSessionAction method to go along
633 // with it. Sending with an action supports sending a "hybrid"
634 // message. Sending with elements must be sent as Jingle or Gingle.
635
636 // When passing elems, must be either Jingle or Gingle protocol.
637 // Takes ownership of action_elems.
638 bool SendMessage(ActionType type, const XmlElements& action_elems,
639 SessionError* error);
640 // When passing an action, may be Hybrid protocol.
641 template <typename Action>
642 bool SendMessage(ActionType type, const Action& action,
643 SessionError* error);
644
645 // Helper methods to write the session message stanza.
646 template <typename Action>
647 bool WriteActionMessage(ActionType type, const Action& action,
648 buzz::XmlElement* stanza, WriteError* error);
649 template <typename Action>
650 bool WriteActionMessage(SignalingProtocol protocol,
651 ActionType type, const Action& action,
652 buzz::XmlElement* stanza, WriteError* error);
653
654 // Sending messages in hybrid form requires being able to write them
655 // on a per-protocol basis with a common method signature, which all
656 // of these have.
657 bool WriteSessionAction(SignalingProtocol protocol,
658 const SessionInitiate& init,
659 XmlElements* elems, WriteError* error);
660 bool WriteSessionAction(SignalingProtocol protocol,
661 const TransportInfo& tinfo,
662 XmlElements* elems, WriteError* error);
663 bool WriteSessionAction(SignalingProtocol protocol,
664 const SessionTerminate& term,
665 XmlElements* elems, WriteError* error);
666
667 // Sends a message back to the other client indicating that we have received
668 // and accepted their message.
669 void SendAcknowledgementMessage(const buzz::XmlElement* stanza);
670
671 // Once signaling is ready, the session will use this signal to request the
672 // sending of each message. When messages are received by the other client,
673 // they should be handed to OnIncomingMessage.
674 // (These are called only by SessionManager.)
675 sigslot::signal2<Session* , const buzz::XmlElement*> SignalOutgoingMessage;
676 void OnIncomingMessage(const SessionMessage& msg);
677
678 void OnIncomingResponse(const buzz::XmlElement* orig_stanza,
679 const buzz::XmlElement* response_stanza,
680 const SessionMessage& msg);
681 void OnInitiateAcked();
682 void OnFailedSend(const buzz::XmlElement* orig_stanza,
683 const buzz::XmlElement* error_stanza);
684
685 // Invoked when an error is found in an incoming message. This is translated
686 // into the appropriate XMPP response by SessionManager.
687 sigslot::signal6<BaseSession*,
688 const buzz::XmlElement*,
689 const buzz::QName&,
690 const std::string&,
691 const std::string&,
692 const buzz::XmlElement*> SignalErrorMessage;
693
694 // Handlers for the various types of messages. These functions may take
695 // pointers to the whole stanza or to just the session element.
696 bool OnInitiateMessage(const SessionMessage& msg, MessageError* error);
697 bool OnAcceptMessage(const SessionMessage& msg, MessageError* error);
698 bool OnRejectMessage(const SessionMessage& msg, MessageError* error);
699 bool OnInfoMessage(const SessionMessage& msg);
700 bool OnTerminateMessage(const SessionMessage& msg, MessageError* error);
701 bool OnTransportInfoMessage(const SessionMessage& msg, MessageError* error);
702 bool OnTransportAcceptMessage(const SessionMessage& msg, MessageError* error);
703 bool OnDescriptionInfoMessage(const SessionMessage& msg, MessageError* error);
704 bool OnRedirectError(const SessionRedirect& redirect, SessionError* error);
705
706 // Verifies that we are in the appropriate state to receive this message.
707 bool CheckState(State state, MessageError* error);
708
709 SessionManager* session_manager_;
710 bool initiate_acked_;
711 std::string local_name_;
712 std::string initiator_name_;
713 std::string remote_name_;
714 SessionClient* client_;
715 TransportParser* transport_parser_;
716 // Keeps track of what protocol we are speaking.
717 SignalingProtocol current_protocol_;
718
719 friend class SessionManager; // For access to constructor, destructor,
720 // and signaling related methods.
721};
722
723} // namespace cricket
724
725#endif // TALK_P2P_BASE_SESSION_H_