/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef _PEER_CONNECTION_IMPL_H_ #define _PEER_CONNECTION_IMPL_H_ #include #include #include #include #include #include "prlock.h" #include "mozilla/RefPtr.h" #include "nsWeakPtr.h" #include "nsAutoPtr.h" #include "nsIWeakReferenceUtils.h" // for the definition of nsWeakPtr #include "IPeerConnection.h" #include "sigslot.h" #include "nricectx.h" #include "nricemediastream.h" #include "nsComponentManagerUtils.h" #include "nsPIDOMWindow.h" #include "nsIUUIDGenerator.h" #include "nsIThread.h" #include "signaling/src/jsep/JsepSession.h" #include "signaling/src/jsep/JsepSessionImpl.h" #include "signaling/src/sdp/SdpMediaSection.h" #include "mozilla/ErrorResult.h" #include "mozilla/dom/PeerConnectionImplEnumsBinding.h" #include "PrincipalChangeObserver.h" #include "StreamTracks.h" #if !defined(MOZILLA_EXTERNAL_LINKAGE) #include "mozilla/TimeStamp.h" #include "mozilla/net/DataChannel.h" #include "VideoUtils.h" #include "VideoSegment.h" #include "mozilla/dom/RTCStatsReportBinding.h" #include "nsIPrincipal.h" #include "mozilla/PeerIdentity.h" #endif namespace test { #ifdef USE_FAKE_PCOBSERVER class AFakePCObserver; #endif } #ifdef USE_FAKE_MEDIA_STREAMS class Fake_DOMMediaStream; class Fake_MediaStreamTrack; #endif class nsGlobalWindow; class nsDOMDataChannel; namespace mozilla { class DataChannel; class DtlsIdentity; class NrIceCtx; class NrIceMediaStream; class NrIceStunServer; class NrIceTurnServer; class MediaPipeline; #ifdef USE_FAKE_MEDIA_STREAMS typedef Fake_DOMMediaStream DOMMediaStream; #else class DOMMediaStream; #endif namespace dom { class RTCCertificate; struct RTCConfiguration; class RTCDTMFSender; struct RTCIceServer; struct RTCOfferOptions; struct RTCRtpParameters; class RTCRtpSender; #ifdef USE_FAKE_MEDIA_STREAMS typedef Fake_MediaStreamTrack MediaStreamTrack; #else class MediaStreamTrack; #endif #ifdef USE_FAKE_PCOBSERVER typedef test::AFakePCObserver PeerConnectionObserver; typedef const char *PCObserverString; #else class PeerConnectionObserver; typedef NS_ConvertUTF8toUTF16 PCObserverString; #endif } } #if defined(__cplusplus) && __cplusplus >= 201103L typedef struct Timecard Timecard; #else #include "timecard.h" #endif // To preserve blame, convert nsresult to ErrorResult with wrappers. These macros // help declare wrappers w/function being wrapped when there are no differences. #define NS_IMETHODIMP_TO_ERRORRESULT(func, rv, ...) \ NS_IMETHODIMP func(__VA_ARGS__); \ void func (__VA_ARGS__, rv) #define NS_IMETHODIMP_TO_ERRORRESULT_RETREF(resulttype, func, rv, ...) \ NS_IMETHODIMP func(__VA_ARGS__, resulttype **result); \ already_AddRefed func (__VA_ARGS__, rv) struct MediaStreamTable; namespace mozilla { using mozilla::dom::PeerConnectionObserver; using mozilla::dom::RTCConfiguration; using mozilla::dom::RTCIceServer; using mozilla::dom::RTCOfferOptions; using mozilla::DOMMediaStream; using mozilla::NrIceCtx; using mozilla::NrIceMediaStream; using mozilla::DtlsIdentity; using mozilla::ErrorResult; using mozilla::NrIceStunServer; using mozilla::NrIceTurnServer; #if !defined(MOZILLA_EXTERNAL_LINKAGE) using mozilla::PeerIdentity; #endif class PeerConnectionWrapper; class PeerConnectionMedia; class RemoteSourceStreamInfo; // Uuid Generator class PCUuidGenerator : public mozilla::JsepUuidGenerator { public: virtual bool Generate(std::string* idp) override; private: nsCOMPtr mGenerator; }; class PeerConnectionConfiguration { public: PeerConnectionConfiguration() : mBundlePolicy(kBundleBalanced), mIceTransportPolicy(NrIceCtx::ICE_POLICY_ALL) {} bool addStunServer(const std::string& addr, uint16_t port, const char* transport) { UniquePtr server(NrIceStunServer::Create(addr, port, transport)); if (!server) { return false; } addStunServer(*server); return true; } bool addTurnServer(const std::string& addr, uint16_t port, const std::string& username, const std::string& pwd, const char* transport) { // TODO(ekr@rtfm.com): Need support for SASLprep for // username and password. Bug # ??? std::vector password(pwd.begin(), pwd.end()); UniquePtr server(NrIceTurnServer::Create(addr, port, username, password, transport)); if (!server) { return false; } addTurnServer(*server); return true; } void addStunServer(const NrIceStunServer& server) { mStunServers.push_back (server); } void addTurnServer(const NrIceTurnServer& server) { mTurnServers.push_back (server); } const std::vector& getStunServers() const { return mStunServers; } const std::vector& getTurnServers() const { return mTurnServers; } void setBundlePolicy(JsepBundlePolicy policy) { mBundlePolicy = policy;} JsepBundlePolicy getBundlePolicy() const { return mBundlePolicy; } void setIceTransportPolicy(NrIceCtx::Policy policy) { mIceTransportPolicy = policy;} NrIceCtx::Policy getIceTransportPolicy() const { return mIceTransportPolicy; } #ifndef MOZILLA_EXTERNAL_LINKAGE nsresult Init(const RTCConfiguration& aSrc); nsresult AddIceServer(const RTCIceServer& aServer); #endif private: std::vector mStunServers; std::vector mTurnServers; JsepBundlePolicy mBundlePolicy; NrIceCtx::Policy mIceTransportPolicy; }; #if !defined(MOZILLA_EXTERNAL_LINKAGE) // Not an inner class so we can forward declare. class RTCStatsQuery { public: explicit RTCStatsQuery(bool internalStats); ~RTCStatsQuery(); nsAutoPtr report; std::string error; // A timestamp to help with telemetry. mozilla::TimeStamp iceStartTime; // Just for convenience, maybe integrate into the report later bool failed; private: friend class PeerConnectionImpl; std::string pcName; bool internalStats; nsTArray> pipelines; RefPtr iceCtx; bool grabAllLevels; DOMHighResTimeStamp now; }; #endif // MOZILLA_INTERNAL_API // Enter an API call and check that the state is OK, // the PC isn't closed, etc. #define PC_AUTO_ENTER_API_CALL(assert_ice_ready) \ do { \ /* do/while prevents res from conflicting with locals */ \ nsresult res = CheckApiState(assert_ice_ready); \ if (NS_FAILED(res)) return res; \ } while(0) #define PC_AUTO_ENTER_API_CALL_VOID_RETURN(assert_ice_ready) \ do { \ /* do/while prevents res from conflicting with locals */ \ nsresult res = CheckApiState(assert_ice_ready); \ if (NS_FAILED(res)) return; \ } while(0) #define PC_AUTO_ENTER_API_CALL_NO_CHECK() CheckThread() class PeerConnectionImpl final : public nsISupports, #if !defined(MOZILLA_EXTERNAL_LINKAGE) public mozilla::DataChannelConnection::DataConnectionListener, public dom::PrincipalChangeObserver, #endif public sigslot::has_slots<> { struct Internal; // Avoid exposing c includes to bindings public: explicit PeerConnectionImpl(const mozilla::dom::GlobalObject* aGlobal = nullptr); enum Error { kNoError = 0, kInvalidCandidate = 2, kInvalidMediastreamTrack = 3, kInvalidState = 4, kInvalidSessionDescription = 5, kIncompatibleSessionDescription = 6, kIncompatibleMediaStreamTrack = 8, kInternalError = 9 }; NS_DECL_THREADSAFE_ISUPPORTS #if !defined(MOZILLA_EXTERNAL_LINKAGE) bool WrapObject(JSContext* aCx, JS::Handle aGivenProto, JS::MutableHandle aReflector); #endif static already_AddRefed Constructor(const mozilla::dom::GlobalObject& aGlobal, ErrorResult& rv); static PeerConnectionImpl* CreatePeerConnection(); already_AddRefed MakeMediaStream(); nsresult CreateRemoteSourceStreamInfo(RefPtr* aInfo, const std::string& aId); // DataConnection observers void NotifyDataChannel(already_AddRefed aChannel) #if !defined(MOZILLA_EXTERNAL_LINKAGE) // PeerConnectionImpl only inherits from mozilla::DataChannelConnection // inside libxul. override #endif ; // Get the media object const RefPtr& media() const { PC_AUTO_ENTER_API_CALL_NO_CHECK(); return mMedia; } // Configure the ability to use localhost. void SetAllowIceLoopback(bool val) { mAllowIceLoopback = val; } bool GetAllowIceLoopback() const { return mAllowIceLoopback; } // Configure the ability to use IPV6 link-local addresses. void SetAllowIceLinkLocal(bool val) { mAllowIceLinkLocal = val; } bool GetAllowIceLinkLocal() const { return mAllowIceLinkLocal; } // Handle system to allow weak references to be passed through C code virtual const std::string& GetHandle(); // Name suitable for exposing to content virtual const std::string& GetName(); // ICE events void IceConnectionStateChange(NrIceCtx* ctx, NrIceCtx::ConnectionState state); void IceGatheringStateChange(NrIceCtx* ctx, NrIceCtx::GatheringState state); void UpdateDefaultCandidate(const std::string& defaultAddr, uint16_t defaultPort, const std::string& defaultRtcpAddr, uint16_t defaultRtcpPort, uint16_t level); void EndOfLocalCandidates(uint16_t level); void IceStreamReady(NrIceMediaStream *aStream); static void ListenThread(void *aData); static void ConnectThread(void *aData); // Get the main thread nsCOMPtr GetMainThread() { PC_AUTO_ENTER_API_CALL_NO_CHECK(); return mThread; } // Get the STS thread nsIEventTarget* GetSTSThread() { PC_AUTO_ENTER_API_CALL_NO_CHECK(); return mSTSThread; } nsPIDOMWindowInner* GetWindow() const { PC_AUTO_ENTER_API_CALL_NO_CHECK(); return mWindow; } // Initialize PeerConnection from a PeerConnectionConfiguration object // (used directly by unit-tests, and indirectly by the JS entry point) // This is necessary because RTCConfiguration can't be used by unit-tests nsresult Initialize(PeerConnectionObserver& aObserver, nsGlobalWindow* aWindow, const PeerConnectionConfiguration& aConfiguration, nsISupports* aThread); #ifndef MOZILLA_EXTERNAL_LINKAGE // Initialize PeerConnection from an RTCConfiguration object (JS entrypoint) void Initialize(PeerConnectionObserver& aObserver, nsGlobalWindow& aWindow, const RTCConfiguration& aConfiguration, nsISupports* aThread, ErrorResult &rv); #endif #if !defined(MOZILLA_EXTERNAL_LINKAGE) void SetCertificate(mozilla::dom::RTCCertificate& aCertificate); const RefPtr& Certificate() const; #endif // This is a hack to support external linkage. RefPtr Identity() const; NS_IMETHODIMP_TO_ERRORRESULT(CreateOffer, ErrorResult &rv, const RTCOfferOptions& aOptions) { rv = CreateOffer(aOptions); } NS_IMETHODIMP CreateAnswer(); void CreateAnswer(ErrorResult &rv) { rv = CreateAnswer(); } NS_IMETHODIMP CreateOffer( const mozilla::JsepOfferOptions& aConstraints); NS_IMETHODIMP SetLocalDescription (int32_t aAction, const char* aSDP); void SetLocalDescription (int32_t aAction, const nsAString& aSDP, ErrorResult &rv) { rv = SetLocalDescription(aAction, NS_ConvertUTF16toUTF8(aSDP).get()); } nsresult CreateNewRemoteTracks(RefPtr& aPco); void RemoveOldRemoteTracks(RefPtr& aPco); NS_IMETHODIMP SetRemoteDescription (int32_t aAction, const char* aSDP); void SetRemoteDescription (int32_t aAction, const nsAString& aSDP, ErrorResult &rv) { rv = SetRemoteDescription(aAction, NS_ConvertUTF16toUTF8(aSDP).get()); } NS_IMETHODIMP_TO_ERRORRESULT(GetStats, ErrorResult &rv, mozilla::dom::MediaStreamTrack *aSelector) { rv = GetStats(aSelector); } NS_IMETHODIMP AddIceCandidate(const char* aCandidate, const char* aMid, unsigned short aLevel); void AddIceCandidate(const nsAString& aCandidate, const nsAString& aMid, unsigned short aLevel, ErrorResult &rv) { rv = AddIceCandidate(NS_ConvertUTF16toUTF8(aCandidate).get(), NS_ConvertUTF16toUTF8(aMid).get(), aLevel); } NS_IMETHODIMP CloseStreams(); void CloseStreams(ErrorResult &rv) { rv = CloseStreams(); } NS_IMETHODIMP_TO_ERRORRESULT(AddTrack, ErrorResult &rv, mozilla::dom::MediaStreamTrack& aTrack, const mozilla::dom::Sequence>& aStreams) { rv = AddTrack(aTrack, aStreams); } NS_IMETHODIMP_TO_ERRORRESULT(RemoveTrack, ErrorResult &rv, mozilla::dom::MediaStreamTrack& aTrack) { rv = RemoveTrack(aTrack); } nsresult AddTrack(mozilla::dom::MediaStreamTrack& aTrack, DOMMediaStream& aStream); NS_IMETHODIMP_TO_ERRORRESULT(InsertDTMF, ErrorResult &rv, dom::RTCRtpSender& sender, const nsAString& tones, uint32_t duration, uint32_t interToneGap) { rv = InsertDTMF(sender, tones, duration, interToneGap); } NS_IMETHODIMP_TO_ERRORRESULT(GetDTMFToneBuffer, ErrorResult &rv, dom::RTCRtpSender& sender, nsAString& outToneBuffer) { rv = GetDTMFToneBuffer(sender, outToneBuffer); } NS_IMETHODIMP_TO_ERRORRESULT(ReplaceTrack, ErrorResult &rv, mozilla::dom::MediaStreamTrack& aThisTrack, mozilla::dom::MediaStreamTrack& aWithTrack) { rv = ReplaceTrack(aThisTrack, aWithTrack); } #if !defined(MOZILLA_EXTERNAL_LINKAGE) NS_IMETHODIMP_TO_ERRORRESULT(SetParameters, ErrorResult &rv, dom::MediaStreamTrack& aTrack, const dom::RTCRtpParameters& aParameters) { rv = SetParameters(aTrack, aParameters); } NS_IMETHODIMP_TO_ERRORRESULT(GetParameters, ErrorResult &rv, dom::MediaStreamTrack& aTrack, dom::RTCRtpParameters& aOutParameters) { rv = GetParameters(aTrack, aOutParameters); } #endif nsresult SetParameters(dom::MediaStreamTrack& aTrack, const std::vector& aConstraints); nsresult GetParameters(dom::MediaStreamTrack& aTrack, std::vector* aOutConstraints); NS_IMETHODIMP_TO_ERRORRESULT(SelectSsrc, ErrorResult &rv, dom::MediaStreamTrack& aRecvTrack, unsigned short aSsrcIndex) { rv = SelectSsrc(aRecvTrack, aSsrcIndex); } nsresult GetPeerIdentity(nsAString& peerIdentity) { #if !defined(MOZILLA_EXTERNAL_LINKAGE) if (mPeerIdentity) { peerIdentity = mPeerIdentity->ToString(); return NS_OK; } #endif peerIdentity.SetIsVoid(true); return NS_OK; } #if !defined(MOZILLA_EXTERNAL_LINKAGE) const PeerIdentity* GetPeerIdentity() const { return mPeerIdentity; } nsresult SetPeerIdentity(const nsAString& peerIdentity); const std::string& GetIdAsAscii() const { return mName; } nsresult GetId(nsAString& id) { id = NS_ConvertASCIItoUTF16(mName.c_str()); return NS_OK; } nsresult SetId(const nsAString& id) { mName = NS_ConvertUTF16toUTF8(id).get(); return NS_OK; } #endif // this method checks to see if we've made a promise to protect media. bool PrivacyRequested() const { return mPrivacyRequested; } NS_IMETHODIMP GetFingerprint(char** fingerprint); void GetFingerprint(nsAString& fingerprint) { char *tmp; nsresult rv = GetFingerprint(&tmp); NS_ENSURE_SUCCESS_VOID(rv); fingerprint.AssignASCII(tmp); delete[] tmp; } NS_IMETHODIMP GetLocalDescription(char** aSDP); void GetLocalDescription(nsAString& aSDP) { char *tmp; GetLocalDescription(&tmp); aSDP.AssignASCII(tmp); delete[] tmp; } NS_IMETHODIMP GetRemoteDescription(char** aSDP); void GetRemoteDescription(nsAString& aSDP) { char *tmp; GetRemoteDescription(&tmp); aSDP.AssignASCII(tmp); delete[] tmp; } NS_IMETHODIMP SignalingState(mozilla::dom::PCImplSignalingState* aState); mozilla::dom::PCImplSignalingState SignalingState() { mozilla::dom::PCImplSignalingState state; SignalingState(&state); return state; } NS_IMETHODIMP IceConnectionState( mozilla::dom::PCImplIceConnectionState* aState); mozilla::dom::PCImplIceConnectionState IceConnectionState() { mozilla::dom::PCImplIceConnectionState state; IceConnectionState(&state); return state; } NS_IMETHODIMP IceGatheringState( mozilla::dom::PCImplIceGatheringState* aState); mozilla::dom::PCImplIceGatheringState IceGatheringState() { mozilla::dom::PCImplIceGatheringState state; IceGatheringState(&state); return state; } NS_IMETHODIMP Close(); void Close(ErrorResult &rv) { rv = Close(); } bool PluginCrash(uint32_t aPluginID, const nsAString& aPluginName); nsresult InitializeDataChannel(); NS_IMETHODIMP_TO_ERRORRESULT_RETREF(nsDOMDataChannel, CreateDataChannel, ErrorResult &rv, const nsAString& aLabel, const nsAString& aProtocol, uint16_t aType, bool outOfOrderAllowed, uint16_t aMaxTime, uint16_t aMaxNum, bool aExternalNegotiated, uint16_t aStream); NS_IMETHODIMP_TO_ERRORRESULT(GetLocalStreams, ErrorResult &rv, nsTArray >& result) { rv = GetLocalStreams(result); } NS_IMETHODIMP_TO_ERRORRESULT(GetRemoteStreams, ErrorResult &rv, nsTArray >& result) { rv = GetRemoteStreams(result); } // Called whenever something is unrecognized by the parser // May be called more than once and does not necessarily mean // that parsing was stopped, only that something was unrecognized. void OnSdpParseError(const char* errorMessage); // Called when OnLocal/RemoteDescriptionSuccess/Error // is called to start the list over. void ClearSdpParseErrorMessages(); // Called to retreive the list of parsing errors. const std::vector &GetSdpParseErrors(); // Sets the RTC Signaling State void SetSignalingState_m(mozilla::dom::PCImplSignalingState aSignalingState, bool rollback = false); // Updates the RTC signaling state based on the JsepSession state void UpdateSignalingState(bool rollback = false); bool IsClosed() const; // called when DTLS connects; we only need this once nsresult SetDtlsConnected(bool aPrivacyRequested); bool HasMedia() const; #if !defined(MOZILLA_EXTERNAL_LINKAGE) nsresult BuildStatsQuery_m( mozilla::dom::MediaStreamTrack *aSelector, RTCStatsQuery *query); static nsresult ExecuteStatsQuery_s(RTCStatsQuery *query); // for monitoring changes in track ownership // PeerConnectionMedia can't do it because it doesn't know about principals virtual void PrincipalChanged(dom::MediaStreamTrack* aTrack) override; #endif static std::string GetStreamId(const DOMMediaStream& aStream); static std::string GetTrackId(const dom::MediaStreamTrack& track); void OnMediaError(const std::string& aError); private: virtual ~PeerConnectionImpl(); PeerConnectionImpl(const PeerConnectionImpl&rhs); PeerConnectionImpl& operator=(PeerConnectionImpl); nsresult CalculateFingerprint(const std::string& algorithm, std::vector* fingerprint) const; nsresult ConfigureJsepSessionCodecs(); NS_IMETHODIMP EnsureDataConnection(uint16_t aNumstreams); nsresult CloseInt(); nsresult CheckApiState(bool assert_ice_ready) const; void CheckThread() const { MOZ_ASSERT(CheckThreadInt(), "Wrong thread"); } bool CheckThreadInt() const { #if !defined(MOZILLA_EXTERNAL_LINKAGE) // Thread assertions are disabled in the C++ unit tests because those // make API calls off the main thread. // This affects the standalone version of WebRTC since it is also used // for an alternate build of the unit tests. // TODO(ekr@rtfm.com): Fix the unit tests so they don't do that. bool on; NS_ENSURE_SUCCESS(mThread->IsOnCurrentThread(&on), false); NS_ENSURE_TRUE(on, false); #endif return true; } #if !defined(MOZILLA_EXTERNAL_LINKAGE) nsresult GetTimeSinceEpoch(DOMHighResTimeStamp *result); #endif // Shut down media - called on main thread only void ShutdownMedia(); void CandidateReady(const std::string& candidate, uint16_t level); void SendLocalIceCandidateToContent(uint16_t level, const std::string& mid, const std::string& candidate); nsresult GetDatachannelParameters( const mozilla::JsepApplicationCodecDescription** codec, uint16_t* level) const; static void DeferredAddTrackToJsepSession(const std::string& pcHandle, SdpMediaSection::MediaType type, const std::string& streamId, const std::string& trackId); nsresult AddTrackToJsepSession(SdpMediaSection::MediaType type, const std::string& streamId, const std::string& trackId); nsresult SetupIceRestart(); nsresult RollbackIceRestart(); void FinalizeIceRestart(); #if !defined(MOZILLA_EXTERNAL_LINKAGE) static void GetStatsForPCObserver_s( const std::string& pcHandle, nsAutoPtr query); // Sends an RTCStatsReport to JS. Must run on main thread. static void DeliverStatsReportToPCObserver_m( const std::string& pcHandle, nsresult result, nsAutoPtr query); #endif // When ICE completes, we record a bunch of statistics that outlive the // PeerConnection. This is just telemetry right now, but this can also // include things like dumping the RLogConnector somewhere, saving away // an RTCStatsReport somewhere so it can be inspected after the call is over, // or other things. void RecordLongtermICEStatistics(); void OnNegotiationNeeded(); static void MaybeFireNegotiationNeeded_static(const std::string& pcHandle); void MaybeFireNegotiationNeeded(); // Timecard used to measure processing time. This should be the first class // attribute so that we accurately measure the time required to instantiate // any other attributes of this class. Timecard *mTimeCard; mozilla::dom::PCImplSignalingState mSignalingState; // ICE State mozilla::dom::PCImplIceConnectionState mIceConnectionState; mozilla::dom::PCImplIceGatheringState mIceGatheringState; // DTLS // this is true if we have been connected ever, see SetDtlsConnected bool mDtlsConnected; nsCOMPtr mThread; // TODO: Remove if we ever properly wire PeerConnection for cycle-collection. nsWeakPtr mPCObserver; nsCOMPtr mWindow; // The SDP sent in from JS - here for debugging. std::string mLocalRequestedSDP; std::string mRemoteRequestedSDP; // DTLS fingerprint std::string mFingerprint; std::string mRemoteFingerprint; // identity-related fields #if !defined(MOZILLA_EXTERNAL_LINKAGE) // The entity on the other end of the peer-to-peer connection; // void if they are not yet identified, and no identity setting has been set RefPtr mPeerIdentity; // The certificate we are using. RefPtr mCertificate; #else RefPtr mIdentity; #endif // Whether an app should be prevented from accessing media produced by the PC // If this is true, then media will not be sent until mPeerIdentity matches // local streams PeerIdentity; and remote streams are protected from content // // This can be false if mPeerIdentity is set, in the case where identity is // provided, but the media is not protected from the app on either side bool mPrivacyRequested; // A handle to refer to this PC with std::string mHandle; // A name for this PC that we are willing to expose to content. std::string mName; // The target to run stuff on nsCOMPtr mSTSThread; #if !defined(MOZILLA_EXTERNAL_LINKAGE) // DataConnection that's used to get all the DataChannels RefPtr mDataConnection; #endif bool mAllowIceLoopback; bool mAllowIceLinkLocal; RefPtr mMedia; // The JSEP negotiation session. mozilla::UniquePtr mUuidGen; mozilla::UniquePtr mJsepSession; std::string mPreviousIceUfrag; // used during rollback of ice restart std::string mPreviousIcePwd; // used during rollback of ice restart #if !defined(MOZILLA_EXTERNAL_LINKAGE) // Start time of ICE, used for telemetry mozilla::TimeStamp mIceStartTime; // Start time of call used for Telemetry mozilla::TimeStamp mStartTime; #endif // Temporary: used to prevent multiple audio streams or multiple video streams // in a single PC. This is tied up in the IETF discussion around proper // representation of multiple streams in SDP, and strongly related to // Bug 840728. int mNumAudioStreams; int mNumVideoStreams; bool mHaveConfiguredCodecs; bool mHaveDataStream; unsigned int mAddCandidateErrorCount; bool mTrickle; bool mNegotiationNeeded; bool mPrivateWindow; // storage for Telemetry data uint16_t mMaxReceiving[SdpMediaSection::kMediaTypes]; uint16_t mMaxSending[SdpMediaSection::kMediaTypes]; // DTMF class DTMFState : public nsITimerCallback { virtual ~DTMFState(); public: DTMFState(); NS_DECL_NSITIMERCALLBACK NS_DECL_THREADSAFE_ISUPPORTS PeerConnectionImpl* mPeerConnectionImpl; nsCOMPtr mSendTimer; nsString mTrackId; nsString mTones; size_t mLevel; uint32_t mDuration; uint32_t mInterToneGap; }; nsTArray> mDTMFStates; public: //these are temporary until the DataChannel Listen/Connect API is removed unsigned short listenPort; unsigned short connectPort; char *connectStr; // XXX ownership/free }; // This is what is returned when you acquire on a handle class PeerConnectionWrapper { public: explicit PeerConnectionWrapper(const std::string& handle); PeerConnectionImpl *impl() { return impl_; } private: RefPtr impl_; }; } // end mozilla namespace #undef NS_IMETHODIMP_TO_ERRORRESULT #undef NS_IMETHODIMP_TO_ERRORRESULT_RETREF #endif // _PEER_CONNECTION_IMPL_H_