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