/* 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 _JSEPSESSIONIMPL_H_ #define _JSEPSESSIONIMPL_H_ #include #include #include #include #include "jsep/JsepCodecDescription.h" #include "jsep/JsepSession.h" #include "jsep/JsepTrack.h" #include "jsep/JsepTransceiver.h" #include "jsep/SsrcGenerator.h" #include "sdp/HybridSdpParser.h" #include "sdp/SdpHelper.h" namespace mozilla { // JsepSessionImpl members that have default copy c'tors, to simplify the // implementation of the copy c'tor for JsepSessionImpl class JsepSessionCopyableStuff { protected: struct JsepDtlsFingerprint { std::string mAlgorithm; std::vector mValue; }; Maybe mIsPendingOfferer; Maybe mIsCurrentOfferer; bool mIceControlling = false; std::string mIceUfrag; std::string mIcePwd; std::string mOldIceUfrag; std::string mOldIcePwd; bool mRemoteIsIceLite = false; std::vector mIceOptions; JsepBundlePolicy mBundlePolicy = kBundleBalanced; std::vector mDtlsFingerprints; uint64_t mSessionId = 0; uint64_t mSessionVersion = 0; size_t mMidCounter = 0; std::set mUsedMids; size_t mTransportIdCounter = 0; std::vector mRtpExtensions; std::set mExtmapEntriesEverUsed; std::map mExtmapEntriesEverNegotiated; std::string mDefaultRemoteStreamId; std::string mCNAME; // Used to prevent duplicate local SSRCs. Not used to prevent local/remote or // remote-only duplication, which will be important for EKT but not now. std::set mSsrcs; std::string mLastError; std::vector> mLastSdpParsingErrors; bool mEncodeTrackId = true; SsrcGenerator mSsrcGenerator; // !!!NOT INDEXED BY LEVEL!!! The level mapping is done with // JsepTransceiver::mLevel. The keys are UUIDs. std::vector mTransceivers; // So we can rollback. Not as simple as just going back to the old, though... std::vector mOldTransceivers; }; class JsepSessionImpl : public JsepSession, public JsepSessionCopyableStuff { public: JsepSessionImpl(const std::string& name, UniquePtr uuidgen) : JsepSession(name), mUuidGen(std::move(uuidgen)), mSdpHelper(&mLastError), mParser(new HybridSdpParser()) {} JsepSessionImpl(const JsepSessionImpl& aOrig); JsepSession* Clone() const override { return new JsepSessionImpl(*this); } // Implement JsepSession methods. virtual nsresult Init() override; nsresult SetBundlePolicy(JsepBundlePolicy policy) override; virtual bool RemoteIsIceLite() const override { return mRemoteIsIceLite; } virtual std::vector GetIceOptions() const override { return mIceOptions; } virtual nsresult AddDtlsFingerprint( const std::string& algorithm, const std::vector& value) override; virtual nsresult AddRtpExtension( JsepMediaType mediaType, const std::string& extensionName, SdpDirectionAttribute::Direction direction) override; virtual nsresult AddAudioRtpExtension( const std::string& extensionName, SdpDirectionAttribute::Direction direction = SdpDirectionAttribute::Direction::kSendrecv) override; virtual nsresult AddVideoRtpExtension( const std::string& extensionName, SdpDirectionAttribute::Direction direction = SdpDirectionAttribute::Direction::kSendrecv) override; virtual nsresult AddAudioVideoRtpExtension( const std::string& extensionName, SdpDirectionAttribute::Direction direction = SdpDirectionAttribute::Direction::kSendrecv) override; virtual std::vector>& Codecs() override { return mSupportedCodecs; } virtual Result CreateOffer(const JsepOfferOptions& options, std::string* offer) override; virtual Result CreateAnswer(const JsepAnswerOptions& options, std::string* answer) override; virtual std::string GetLocalDescription( JsepDescriptionPendingOrCurrent type) const override; virtual std::string GetRemoteDescription( JsepDescriptionPendingOrCurrent type) const override; virtual Result SetLocalDescription(JsepSdpType type, const std::string& sdp) override; virtual Result SetRemoteDescription(JsepSdpType type, const std::string& sdp) override; virtual Result AddRemoteIceCandidate(const std::string& candidate, const std::string& mid, const Maybe& level, const std::string& ufrag, std::string* transportId) override; virtual nsresult AddLocalIceCandidate(const std::string& candidate, const std::string& transportId, const std::string& ufrag, uint16_t* level, std::string* mid, bool* skipped) override; virtual nsresult UpdateDefaultCandidate( const std::string& defaultCandidateAddr, uint16_t defaultCandidatePort, const std::string& defaultRtcpCandidateAddr, uint16_t defaultRtcpCandidatePort, const std::string& transportId) override; virtual nsresult Close() override; virtual const std::string GetLastError() const override; virtual const std::vector>& GetLastSdpParsingErrors() const override; virtual bool IsIceControlling() const override { return mIceControlling; } virtual Maybe IsPendingOfferer() const override { return mIsPendingOfferer; } virtual Maybe IsCurrentOfferer() const override { return mIsCurrentOfferer; } virtual bool IsIceRestarting() const override { return !mOldIceUfrag.empty(); } virtual std::set> GetLocalIceCredentials() const override; virtual void AddTransceiver(const JsepTransceiver& transceiver) override; virtual bool CheckNegotiationNeeded() const override; virtual void SetDefaultCodecs( const std::vector>& aPreferredCodecs) override; private: friend class JsepSessionTest; virtual const std::vector& GetTransceivers() const override { return mTransceivers; } virtual std::vector& GetTransceivers() override { return mTransceivers; } // Non-const so it can set mLastError nsresult CreateGenericSDP(UniquePtr* sdp); void AddExtmap(SdpMediaSection* msection); std::vector GetRtpExtensions( const SdpMediaSection& msection); std::string GetNewMid(); void AddCommonExtmaps(const SdpMediaSection& remoteMsection, SdpMediaSection* msection); uint16_t GetNeverUsedExtmapEntry(); nsresult SetupIds(); void SetState(JsepSignalingState state); // Non-const so it can set mLastError nsresult ParseSdp(const std::string& sdp, UniquePtr* parsedp); nsresult SetLocalDescriptionOffer(UniquePtr offer); nsresult SetLocalDescriptionAnswer(JsepSdpType type, UniquePtr answer); nsresult SetRemoteDescriptionOffer(UniquePtr offer); nsresult SetRemoteDescriptionAnswer(JsepSdpType type, UniquePtr answer); nsresult ValidateLocalDescription(const Sdp& description, JsepSdpType type); nsresult ValidateRemoteDescription(const Sdp& description); nsresult ValidateOffer(const Sdp& offer); nsresult ValidateAnswer(const Sdp& offer, const Sdp& answer); nsresult UpdateTransceiversFromRemoteDescription(const Sdp& remote); Maybe GetTransceiverForLevel(size_t level) const; Maybe GetTransceiverForMid(const std::string& mid) const; Maybe GetTransceiverForLocal(size_t level); Maybe GetTransceiverForRemote( const SdpMediaSection& msection); Maybe GetTransceiverWithTransport( const std::string& transportId) const; // The w3c and IETF specs have a lot of "magical" behavior that happens when // addTrack is used. This was a deliberate design choice. Sadface. Maybe FindUnassociatedTransceiver( SdpMediaSection::MediaType type, bool magic); // Called for rollback of local description void RollbackLocalOffer(); // Called for rollback of remote description void RollbackRemoteOffer(); nsresult HandleNegotiatedSession(const UniquePtr& local, const UniquePtr& remote); nsresult AddTransportAttributes(SdpMediaSection* msection, SdpSetupAttribute::Role dtlsRole); nsresult CopyPreviousTransportParams(const Sdp& oldAnswer, const Sdp& offerersPreviousSdp, const Sdp& newOffer, Sdp* newLocal); void EnsureMsid(Sdp* remote); void SetupBundle(Sdp* sdp) const; nsresult CreateOfferMsection(const JsepOfferOptions& options, JsepTransceiver& transceiver, Sdp* local); nsresult CreateAnswerMsection(const JsepAnswerOptions& options, JsepTransceiver& transceiver, const SdpMediaSection& remoteMsection, Sdp* sdp); nsresult DetermineAnswererSetupRole(const SdpMediaSection& remoteMsection, SdpSetupAttribute::Role* rolep); nsresult MakeNegotiatedTransceiver(const SdpMediaSection& remote, const SdpMediaSection& local, JsepTransceiver& transceiverOut); void EnsureHasOwnTransport(const SdpMediaSection& msection, JsepTransceiver& transceiver); void CopyBundleTransports(); nsresult FinalizeTransport(const SdpAttributeList& remote, const SdpAttributeList& answer, JsepTransport* transport) const; nsresult GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids); nsresult EnableOfferMsection(SdpMediaSection* msection); mozilla::Sdp* GetParsedLocalDescription( JsepDescriptionPendingOrCurrent type) const; mozilla::Sdp* GetParsedRemoteDescription( JsepDescriptionPendingOrCurrent type) const; const Sdp* GetAnswer() const; void SetIceRestarting(bool restarting); void InitTransceiver(JsepTransceiver& aTransceiver); UniquePtr mUuidGen; UniquePtr mGeneratedOffer; // Created but not set. UniquePtr mGeneratedAnswer; // Created but not set. UniquePtr mCurrentLocalDescription; UniquePtr mCurrentRemoteDescription; UniquePtr mPendingLocalDescription; UniquePtr mPendingRemoteDescription; std::vector> mSupportedCodecs; SdpHelper mSdpHelper; UniquePtr mParser; }; } // namespace mozilla #endif