JsepTransceiver.h (6014B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this file, 3 * You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 #ifndef _JSEPTRANSCEIVER_H_ 6 #define _JSEPTRANSCEIVER_H_ 7 8 #include <string> 9 10 #include "jsep/JsepTrack.h" 11 #include "jsep/JsepTransport.h" 12 #include "nsError.h" 13 #include "sdp/Sdp.h" 14 #include "sdp/SdpAttribute.h" 15 #include "sdp/SdpMediaSection.h" 16 17 namespace mozilla { 18 19 class JsepUuidGenerator { 20 public: 21 virtual ~JsepUuidGenerator() = default; 22 virtual bool Generate(std::string* id) = 0; 23 virtual JsepUuidGenerator* Clone() const = 0; 24 }; 25 26 class JsepTransceiver { 27 public: 28 explicit JsepTransceiver(SdpMediaSection::MediaType type, 29 JsepUuidGenerator& aUuidGen, 30 SdpDirectionAttribute::Direction jsDirection = 31 SdpDirectionAttribute::kSendrecv) 32 : mJsDirection(jsDirection), 33 mSendTrack(type, sdp::kSend), 34 mRecvTrack(type, sdp::kRecv) { 35 if (!aUuidGen.Generate(&mUuid)) { 36 MOZ_CRASH(); 37 } 38 } 39 40 JsepTransceiver(const JsepTransceiver& orig) = default; 41 JsepTransceiver(JsepTransceiver&& orig) = default; 42 JsepTransceiver& operator=(const JsepTransceiver& aRhs) = default; 43 JsepTransceiver& operator=(JsepTransceiver&& aRhs) = default; 44 45 ~JsepTransceiver() = default; 46 47 void Rollback(JsepTransceiver& oldTransceiver, bool aRemote) { 48 MOZ_ASSERT(oldTransceiver.GetMediaType() == GetMediaType()); 49 MOZ_ASSERT(!oldTransceiver.IsNegotiated() || !oldTransceiver.HasLevel() || 50 !HasLevel() || oldTransceiver.GetLevel() == GetLevel()); 51 mTransport = oldTransceiver.mTransport; 52 if (aRemote) { 53 mLevel = oldTransceiver.mLevel; 54 mBundleLevel = oldTransceiver.mBundleLevel; 55 mSendTrack = oldTransceiver.mSendTrack; 56 } 57 mRecvTrack = oldTransceiver.mRecvTrack; 58 59 // Don't allow rollback to re-associate a transceiver. 60 if (!oldTransceiver.IsAssociated()) { 61 Disassociate(); 62 } 63 } 64 65 bool IsAssociated() const { return !mMid.empty(); } 66 67 const std::string& GetMid() const { 68 MOZ_ASSERT(IsAssociated()); 69 return mMid; 70 } 71 72 void Associate(const std::string& mid) { 73 MOZ_ASSERT(HasLevel()); 74 mMid = mid; 75 } 76 77 void Disassociate() { mMid.clear(); } 78 79 bool HasLevel() const { return mLevel != SIZE_MAX; } 80 81 void SetLevel(size_t level) { 82 MOZ_ASSERT(level != SIZE_MAX); 83 MOZ_ASSERT(!HasLevel()); 84 MOZ_ASSERT(!IsStopped()); 85 86 mLevel = level; 87 } 88 89 void ClearLevel() { 90 MOZ_ASSERT(!IsAssociated()); 91 mLevel = SIZE_MAX; 92 mBundleLevel = SIZE_MAX; 93 } 94 95 size_t GetLevel() const { 96 MOZ_ASSERT(HasLevel()); 97 return mLevel; 98 } 99 100 void Stop() { mStopping = true; } 101 102 bool IsStopping() const { return mStopping; } 103 104 bool IsStopped() const { return mStopped; } 105 106 void SetStopped() { mStopped = true; } 107 108 bool IsFreeToUse() const { return !mStopping && !mStopped && !HasLevel(); } 109 110 void RestartDatachannelTransceiver() { 111 MOZ_RELEASE_ASSERT(GetMediaType() == SdpMediaSection::kApplication); 112 mStopping = false; 113 mStopped = false; 114 mCanRecycleMyMsection = false; 115 } 116 117 void SetRemoved() { mRemoved = true; } 118 119 bool IsRemoved() const { return mRemoved; } 120 121 bool HasBundleLevel() const { return mBundleLevel != SIZE_MAX; } 122 123 size_t BundleLevel() const { 124 MOZ_ASSERT(HasBundleLevel()); 125 return mBundleLevel; 126 } 127 128 void SetBundleLevel(size_t aBundleLevel) { 129 MOZ_ASSERT(aBundleLevel != SIZE_MAX); 130 mBundleLevel = aBundleLevel; 131 } 132 133 void ClearBundleLevel() { mBundleLevel = SIZE_MAX; } 134 135 size_t GetTransportLevel() const { 136 MOZ_ASSERT(HasLevel()); 137 if (HasBundleLevel()) { 138 return BundleLevel(); 139 } 140 return GetLevel(); 141 } 142 143 void SetAddTrackMagic() { mAddTrackMagic = true; } 144 145 bool HasAddTrackMagic() const { return mAddTrackMagic; } 146 147 void SetOnlyExistsBecauseOfSetRemote(bool aValue) { 148 mOnlyExistsBecauseOfSetRemote = aValue; 149 } 150 151 bool OnlyExistsBecauseOfSetRemote() const { 152 return mOnlyExistsBecauseOfSetRemote; 153 } 154 155 void SetNegotiated() { 156 MOZ_ASSERT(IsAssociated()); 157 MOZ_ASSERT(HasLevel()); 158 mNegotiated = true; 159 } 160 161 bool IsNegotiated() const { return mNegotiated; } 162 163 void SetCanRecycleMyMsection() { mCanRecycleMyMsection = true; } 164 165 bool CanRecycleMyMsection() const { return mCanRecycleMyMsection; } 166 167 const std::string& GetUuid() const { return mUuid; } 168 169 // Convenience function 170 SdpMediaSection::MediaType GetMediaType() const { 171 MOZ_ASSERT(mRecvTrack.GetMediaType() == mSendTrack.GetMediaType()); 172 return mRecvTrack.GetMediaType(); 173 } 174 175 bool HasTransport() const { return mTransport.mComponents != 0; } 176 177 bool HasOwnTransport() const { 178 if (HasTransport() && 179 (!HasBundleLevel() || (GetLevel() == BundleLevel()))) { 180 return true; 181 } 182 return false; 183 } 184 185 // See Bug 1642419, this can be removed when all sites are working with RTX. 186 void SetRtxIsAllowed(bool aRtxIsAllowed) { 187 mSendTrack.SetRtxIsAllowed(aRtxIsAllowed); 188 mRecvTrack.SetRtxIsAllowed(aRtxIsAllowed); 189 } 190 191 // This is the direction JS wants. It might not actually happen. 192 SdpDirectionAttribute::Direction mJsDirection; 193 194 JsepTrack mSendTrack; 195 JsepTrack mRecvTrack; 196 JsepTransport mTransport; 197 198 private: 199 std::string mUuid; 200 // Stuff that is not negotiated 201 std::string mMid; 202 size_t mLevel = SIZE_MAX; // SIZE_MAX if no level 203 // Is this track pair sharing a transport with another? 204 size_t mBundleLevel = SIZE_MAX; // SIZE_MAX if no bundle level 205 // The w3c and IETF specs have a lot of "magical" behavior that happens 206 // when addTrack is used to create a transceiver. This was a deliberate 207 // design choice. Sadface. 208 bool mAddTrackMagic = false; 209 bool mOnlyExistsBecauseOfSetRemote = false; 210 bool mStopping = false; 211 bool mStopped = false; 212 bool mRemoved = false; 213 bool mNegotiated = false; 214 bool mCanRecycleMyMsection = false; 215 }; 216 217 } // namespace mozilla 218 219 #endif // _JSEPTRANSCEIVER_H_