Index: webrtc/p2p/base/session.h |
diff --git a/webrtc/p2p/base/session.h b/webrtc/p2p/base/session.h |
index d8721fd0f868bd43d3f711f6fdc63bea107af3e0..8d7aa21c222b3c19d42ac943d3666d3a05f72cb2 100644 |
--- a/webrtc/p2p/base/session.h |
+++ b/webrtc/p2p/base/session.h |
@@ -16,14 +16,14 @@ |
#include <string> |
#include <vector> |
+#include "webrtc/p2p/base/candidate.h" |
+#include "webrtc/p2p/base/port.h" |
+#include "webrtc/p2p/base/transport.h" |
#include "webrtc/base/refcount.h" |
#include "webrtc/base/rtccertificate.h" |
#include "webrtc/base/scoped_ptr.h" |
#include "webrtc/base/scoped_ref_ptr.h" |
#include "webrtc/base/socketaddress.h" |
-#include "webrtc/p2p/base/candidate.h" |
-#include "webrtc/p2p/base/port.h" |
-#include "webrtc/p2p/base/transport.h" |
namespace cricket { |
@@ -31,8 +31,136 @@ |
class P2PTransportChannel; |
class Transport; |
class TransportChannel; |
+class TransportChannelProxy; |
class TransportChannelImpl; |
-class TransportController; |
+ |
+typedef rtc::RefCountedObject<rtc::scoped_ptr<Transport> > |
+TransportWrapper; |
+ |
+// Bundles a Transport and ChannelMap together. ChannelMap is used to |
+// create transport channels before receiving or sending a session |
+// initiate, and for speculatively connecting channels. Previously, a |
+// session had one ChannelMap and transport. Now, with multiple |
+// transports per session, we need multiple ChannelMaps as well. |
+ |
+typedef std::map<int, TransportChannelProxy*> ChannelMap; |
+ |
+class TransportProxy : public sigslot::has_slots<> { |
+ public: |
+ TransportProxy( |
+ rtc::Thread* worker_thread, |
+ const std::string& sid, |
+ const std::string& content_name, |
+ TransportWrapper* transport) |
+ : worker_thread_(worker_thread), |
+ sid_(sid), |
+ content_name_(content_name), |
+ transport_(transport), |
+ connecting_(false), |
+ negotiated_(false), |
+ sent_candidates_(false), |
+ candidates_allocated_(false), |
+ local_description_set_(false), |
+ remote_description_set_(false) { |
+ transport_->get()->SignalCandidatesReady.connect( |
+ this, &TransportProxy::OnTransportCandidatesReady); |
+ } |
+ ~TransportProxy(); |
+ |
+ const std::string& content_name() const { return content_name_; } |
+ // TODO(juberti): It's not good form to expose the object you're wrapping, |
+ // since callers can mutate it. Can we make this return a const Transport*? |
+ Transport* impl() const { return transport_->get(); } |
+ |
+ const std::string& type() const; |
+ bool negotiated() const { return negotiated_; } |
+ const Candidates& sent_candidates() const { return sent_candidates_; } |
+ const Candidates& unsent_candidates() const { return unsent_candidates_; } |
+ bool candidates_allocated() const { return candidates_allocated_; } |
+ void set_candidates_allocated(bool allocated) { |
+ candidates_allocated_ = allocated; |
+ } |
+ |
+ TransportChannel* GetChannel(int component); |
+ TransportChannel* CreateChannel(int component); |
+ bool HasChannel(int component); |
+ void DestroyChannel(int component); |
+ |
+ void AddSentCandidates(const Candidates& candidates); |
+ void AddUnsentCandidates(const Candidates& candidates); |
+ void ClearSentCandidates() { sent_candidates_.clear(); } |
+ void ClearUnsentCandidates() { unsent_candidates_.clear(); } |
+ |
+ // Start the connection process for any channels, creating impls if needed. |
+ void ConnectChannels(); |
+ // Hook up impls to the proxy channels. Doesn't change connect state. |
+ void CompleteNegotiation(); |
+ |
+ // Mux this proxy onto the specified proxy's transport. |
+ bool SetupMux(TransportProxy* proxy); |
+ |
+ // Simple functions that thunk down to the same functions on Transport. |
+ void SetIceRole(IceRole role); |
+ void SetCertificate( |
+ const rtc::scoped_refptr<rtc::RTCCertificate>& certificate); |
+ bool SetLocalTransportDescription(const TransportDescription& description, |
+ ContentAction action, |
+ std::string* error_desc); |
+ bool SetRemoteTransportDescription(const TransportDescription& description, |
+ ContentAction action, |
+ std::string* error_desc); |
+ void OnSignalingReady(); |
+ bool OnRemoteCandidates(const Candidates& candidates, std::string* error); |
+ |
+ // Called when a transport signals that it has new candidates. |
+ void OnTransportCandidatesReady(cricket::Transport* transport, |
+ const Candidates& candidates) { |
+ SignalCandidatesReady(this, candidates); |
+ } |
+ |
+ bool local_description_set() const { |
+ return local_description_set_; |
+ } |
+ bool remote_description_set() const { |
+ return remote_description_set_; |
+ } |
+ |
+ // Handles sending of ready candidates and receiving of remote candidates. |
+ sigslot::signal2<TransportProxy*, |
+ const std::vector<Candidate>&> SignalCandidatesReady; |
+ |
+ private: |
+ TransportChannelProxy* GetChannelProxy(int component) const; |
+ |
+ // Creates a new channel on the Transport which causes the reference |
+ // count to increment. |
+ void CreateChannelImpl(int component); |
+ void CreateChannelImpl_w(int component); |
+ |
+ // Manipulators of transportchannelimpl in channel proxy. |
+ void SetChannelImplFromTransport(TransportChannelProxy* proxy, int component); |
+ void SetChannelImplFromTransport_w(TransportChannelProxy* proxy, |
+ int component); |
+ void ReplaceChannelImpl(TransportChannelProxy* proxy, |
+ TransportChannelImpl* impl); |
+ void ReplaceChannelImpl_w(TransportChannelProxy* proxy, |
+ TransportChannelImpl* impl); |
+ |
+ rtc::Thread* const worker_thread_; |
+ const std::string sid_; |
+ const std::string content_name_; |
+ rtc::scoped_refptr<TransportWrapper> transport_; |
+ bool connecting_; |
+ bool negotiated_; |
+ ChannelMap channels_; |
+ Candidates sent_candidates_; |
+ Candidates unsent_candidates_; |
+ bool candidates_allocated_; |
+ bool local_description_set_; |
+ bool remote_description_set_; |
+}; |
+ |
+typedef std::map<std::string, TransportProxy*> TransportMap; |
// Statistics for all the transports of this session. |
typedef std::map<std::string, TransportStats> TransportStatsMap; |
@@ -96,6 +224,7 @@ |
rtc::Thread* worker_thread, |
PortAllocator* port_allocator, |
const std::string& sid, |
+ const std::string& content_type, |
bool initiator); |
virtual ~BaseSession(); |
@@ -107,6 +236,14 @@ |
// The ID of this session. |
const std::string& id() const { return sid_; } |
+ // TODO(juberti): This data is largely redundant, as it can now be obtained |
+ // from local/remote_description(). Remove these functions and members. |
+ // Returns the XML namespace identifying the type of this session. |
+ const std::string& content_type() const { return content_type_; } |
+ |
+ // Indicates whether we initiated this session. |
+ bool initiator() const { return initiator_; } |
+ |
// Returns the application-level description given by our client. |
// If we are the recipient, this will be NULL until we send an accept. |
const SessionDescription* local_description() const; |
@@ -122,9 +259,6 @@ |
// Takes ownership of SessionDescription* |
void set_remote_description(SessionDescription* sdesc); |
- |
- void set_initiator(bool initiator); |
- bool initiator() const { return initiator_; } |
const SessionDescription* initiator_description() const; |
@@ -146,28 +280,150 @@ |
// TODO(ronghuawu): remove the SetError method that doesn't take |error_desc|. |
virtual void SetError(Error error, const std::string& error_desc); |
+ // Fired when the remote description is updated, with the updated |
+ // contents. |
+ sigslot::signal2<BaseSession* , const ContentInfos&> |
+ SignalRemoteDescriptionUpdate; |
+ |
+ // Fired when SetState is called (regardless if there's a state change), which |
+ // indicates the session description might have be updated. |
+ sigslot::signal2<BaseSession*, ContentAction> SignalNewLocalDescription; |
+ |
+ // Fired when SetState is called (regardless if there's a state change), which |
+ // indicates the session description might have be updated. |
+ sigslot::signal2<BaseSession*, ContentAction> SignalNewRemoteDescription; |
+ |
+ // Returns the transport that has been negotiated or NULL if |
+ // negotiation is still in progress. |
+ virtual Transport* GetTransport(const std::string& content_name); |
+ |
+ // Creates a new channel with the given names. This method may be called |
+ // immediately after creating the session. However, the actual |
+ // implementation may not be fixed until transport negotiation completes. |
+ // This will usually be called from the worker thread, but that |
+ // shouldn't be an issue since the main thread will be blocked in |
+ // Send when doing so. |
+ virtual TransportChannel* CreateChannel(const std::string& content_name, |
+ int component); |
+ |
+ // Returns the channel with the given names. |
+ virtual TransportChannel* GetChannel(const std::string& content_name, |
+ int component); |
+ |
+ // Destroys the channel with the given names. |
+ // This will usually be called from the worker thread, but that |
+ // shouldn't be an issue since the main thread will be blocked in |
+ // Send when doing so. |
+ virtual void DestroyChannel(const std::string& content_name, |
+ int component); |
+ |
+ // Set the ice connection receiving timeout. |
void SetIceConnectionReceivingTimeout(int timeout_ms); |
- // Start gathering candidates for any new transports, or transports doing an |
- // ICE restart. |
- void MaybeStartGathering(); |
+ // For testing. |
+ const rtc::scoped_refptr<rtc::RTCCertificate>& |
+ certificate_for_testing() const { |
+ return certificate_; |
+ } |
protected: |
+ // Specifies the identity to use in this session. |
+ bool SetCertificate( |
+ const rtc::scoped_refptr<rtc::RTCCertificate>& certificate); |
+ |
+ bool SetSslMaxProtocolVersion(rtc::SSLProtocolVersion version); |
+ |
bool PushdownTransportDescription(ContentSource source, |
ContentAction action, |
std::string* error_desc); |
+ void set_initiator(bool initiator) { initiator_ = initiator; } |
+ |
+ const TransportMap& transport_proxies() const { return transports_; } |
+ // Get a TransportProxy by content_name or transport. NULL if not found. |
+ TransportProxy* GetTransportProxy(const std::string& content_name); |
+ void DestroyTransportProxy(const std::string& content_name); |
+ // TransportProxy is owned by session. Return proxy just for convenience. |
+ TransportProxy* GetOrCreateTransportProxy(const std::string& content_name); |
+ // Creates the actual transport object. Overridable for testing. |
+ virtual Transport* CreateTransport(const std::string& content_name); |
+ |
+ void OnSignalingReady(); |
+ void SpeculativelyConnectAllTransportChannels(); |
+ // Helper method to provide remote candidates to the transport. |
+ bool OnRemoteCandidates(const std::string& content_name, |
+ const Candidates& candidates, |
+ std::string* error); |
+ |
+ // This method will mux transport channels by content_name. |
+ // First content is used for muxing. |
+ bool MaybeEnableMuxingSupport(); |
+ |
+ // Called when a transport requests signaling. |
+ virtual void OnTransportRequestSignaling(Transport* transport) { |
+ } |
+ |
+ // Called when the first channel of a transport begins connecting. We use |
+ // this to start a timer, to make sure that the connection completes in a |
+ // reasonable amount of time. |
+ virtual void OnTransportConnecting(Transport* transport) { |
+ } |
+ |
+ // Called when a transport changes its writable state. We track this to make |
+ // sure that the transport becomes writable within a reasonable amount of |
+ // time. If this does not occur, we signal an error. |
+ virtual void OnTransportWritable(Transport* transport) { |
+ } |
+ virtual void OnTransportReadable(Transport* transport) { |
+ } |
+ |
+ virtual void OnTransportReceiving(Transport* transport) { |
+ } |
+ |
+ // Called when a transport has found its steady-state connections. |
+ virtual void OnTransportCompleted(Transport* transport) { |
+ } |
+ |
+ // Called when a transport has failed permanently. |
+ virtual void OnTransportFailed(Transport* transport) { |
+ } |
+ |
+ // Called when a transport signals that it has new candidates. |
+ virtual void OnTransportProxyCandidatesReady(TransportProxy* proxy, |
+ const Candidates& candidates) { |
+ } |
+ |
+ virtual void OnTransportRouteChange( |
+ Transport* transport, |
+ int component, |
+ const cricket::Candidate& remote_candidate) { |
+ } |
+ |
+ virtual void OnTransportCandidatesAllocationDone(Transport* transport); |
+ |
+ // Called when all transport channels allocated required candidates. |
+ // This method should be used as an indication of candidates gathering process |
+ // is completed and application can now send local candidates list to remote. |
+ virtual void OnCandidatesAllocationDone() { |
+ } |
+ |
+ // Handles the ice role change callback from Transport. This must be |
+ // propagated to all the transports. |
+ virtual void OnRoleConflict(); |
// Handles messages posted to us. |
virtual void OnMessage(rtc::Message *pmsg); |
- TransportController* transport_controller() { |
- return transport_controller_.get(); |
- } |
- |
protected: |
+ bool IsCandidateAllocationDone() const; |
+ |
State state_; |
Error error_; |
std::string error_desc_; |
+ |
+ // This method will delete the Transport and TransportChannelImpls |
+ // and replace those with the Transport object of the first |
+ // MediaContent in bundle_group. |
+ bool BundleContentGroup(const ContentGroup* bundle_group); |
private: |
// Helper methods to push local and remote transport descriptions. |
@@ -178,6 +434,8 @@ |
const SessionDescription* sdesc, ContentAction action, |
std::string* error_desc); |
+ void MaybeCandidateAllocationDone(); |
+ |
// Log session state. |
void LogState(State old_state, State new_state); |
@@ -191,10 +449,21 @@ |
rtc::Thread* const worker_thread_; |
PortAllocator* const port_allocator_; |
const std::string sid_; |
+ const std::string content_type_; |
bool initiator_; |
- rtc::scoped_ptr<TransportController> transport_controller_; |
+ rtc::scoped_refptr<rtc::RTCCertificate> certificate_; |
+ rtc::SSLProtocolVersion ssl_max_version_; |
rtc::scoped_ptr<const SessionDescription> local_description_; |
rtc::scoped_ptr<SessionDescription> remote_description_; |
+ uint64 ice_tiebreaker_; |
+ // This flag will be set to true after the first role switch. This flag |
+ // will enable us to stop any role switch during the call. |
+ bool role_switch_; |
+ TransportMap transports_; |
+ |
+ // Timeout value in milliseconds for which no ICE connection receives |
+ // any packets. |
+ int ice_receiving_timeout_; |
}; |
} // namespace cricket |