| 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
|
|
|