summaryrefslogtreecommitdiffstats
path: root/dom/media/webrtc/jsep/JsepSession.h
diff options
context:
space:
mode:
Diffstat (limited to 'dom/media/webrtc/jsep/JsepSession.h')
-rw-r--r--dom/media/webrtc/jsep/JsepSession.h287
1 files changed, 287 insertions, 0 deletions
diff --git a/dom/media/webrtc/jsep/JsepSession.h b/dom/media/webrtc/jsep/JsepSession.h
new file mode 100644
index 0000000000..bf68da900b
--- /dev/null
+++ b/dom/media/webrtc/jsep/JsepSession.h
@@ -0,0 +1,287 @@
+/* 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 _JSEPSESSION_H_
+#define _JSEPSESSION_H_
+
+#include <map>
+#include <string>
+#include <vector>
+#include "mozilla/Attributes.h"
+#include "mozilla/Maybe.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/UniquePtr.h"
+#include "nsError.h"
+
+#include "jsep/JsepTransport.h"
+#include "sdp/Sdp.h"
+
+#include "jsep/JsepTransceiver.h"
+
+#include "mozilla/dom/PeerConnectionObserverEnumsBinding.h"
+
+namespace mozilla {
+
+// Forward declarations
+class JsepCodecDescription;
+
+enum JsepSignalingState {
+ kJsepStateStable,
+ kJsepStateHaveLocalOffer,
+ kJsepStateHaveRemoteOffer,
+ kJsepStateHaveLocalPranswer,
+ kJsepStateHaveRemotePranswer,
+ kJsepStateClosed
+};
+
+enum JsepSdpType {
+ kJsepSdpOffer,
+ kJsepSdpAnswer,
+ kJsepSdpPranswer,
+ kJsepSdpRollback
+};
+
+enum JsepDescriptionPendingOrCurrent {
+ kJsepDescriptionCurrent,
+ kJsepDescriptionPending,
+ kJsepDescriptionPendingOrCurrent
+};
+
+struct JsepOAOptions {};
+struct JsepOfferOptions : public JsepOAOptions {
+ Maybe<size_t> mOfferToReceiveAudio;
+ Maybe<size_t> mOfferToReceiveVideo;
+ Maybe<bool> mIceRestart; // currently ignored by JsepSession
+};
+struct JsepAnswerOptions : public JsepOAOptions {};
+
+enum JsepBundlePolicy { kBundleBalanced, kBundleMaxCompat, kBundleMaxBundle };
+
+enum JsepMediaType { kNone = 0, kAudio, kVideo, kAudioVideo };
+
+struct JsepExtmapMediaType {
+ JsepMediaType mMediaType;
+ SdpExtmapAttributeList::Extmap mExtmap;
+};
+
+class JsepSession {
+ public:
+ explicit JsepSession(const std::string& name)
+ : mName(name), mState(kJsepStateStable), mNegotiations(0) {}
+ virtual ~JsepSession() {}
+
+ virtual JsepSession* Clone() const = 0;
+
+ virtual nsresult Init() = 0;
+
+ // Accessors for basic properties.
+ virtual const std::string& GetName() const { return mName; }
+ virtual JsepSignalingState GetState() const { return mState; }
+ virtual uint32_t GetNegotiations() const { return mNegotiations; }
+
+ // Set up the ICE And DTLS data.
+ virtual nsresult SetBundlePolicy(JsepBundlePolicy policy) = 0;
+ virtual bool RemoteIsIceLite() const = 0;
+ virtual std::vector<std::string> GetIceOptions() const = 0;
+
+ virtual nsresult AddDtlsFingerprint(const std::string& algorithm,
+ const std::vector<uint8_t>& value) = 0;
+
+ virtual nsresult AddRtpExtension(
+ JsepMediaType mediaType, const std::string& extensionName,
+ SdpDirectionAttribute::Direction direction) = 0;
+ virtual nsresult AddAudioRtpExtension(
+ const std::string& extensionName,
+ SdpDirectionAttribute::Direction direction) = 0;
+ virtual nsresult AddVideoRtpExtension(
+ const std::string& extensionName,
+ SdpDirectionAttribute::Direction direction) = 0;
+ virtual nsresult AddAudioVideoRtpExtension(
+ const std::string& extensionName,
+ SdpDirectionAttribute::Direction direction) = 0;
+
+ // Kinda gross to be locking down the data structure type like this, but
+ // returning by value is problematic due to the lack of stl move semantics in
+ // our build config, since we can't use UniquePtr in the container. The
+ // alternative is writing a raft of accessor functions that allow arbitrary
+ // manipulation (which will be unwieldy), or allowing functors to be injected
+ // that manipulate the data structure (still pretty unwieldy).
+ virtual std::vector<UniquePtr<JsepCodecDescription>>& Codecs() = 0;
+
+ template <class UnaryFunction>
+ void ForEachCodec(UnaryFunction& function) {
+ std::for_each(Codecs().begin(), Codecs().end(), function);
+ for (auto& transceiver : GetTransceivers()) {
+ transceiver.mSendTrack.ForEachCodec(function);
+ transceiver.mRecvTrack.ForEachCodec(function);
+ }
+ }
+
+ template <class BinaryPredicate>
+ void SortCodecs(BinaryPredicate& sorter) {
+ std::stable_sort(Codecs().begin(), Codecs().end(), sorter);
+ for (auto& transceiver : GetTransceivers()) {
+ transceiver.mSendTrack.SortCodecs(sorter);
+ transceiver.mRecvTrack.SortCodecs(sorter);
+ }
+ }
+
+ // Would be nice to have this return a Maybe containing the return of
+ // |aFunction|, but Maybe cannot contain a void.
+ template <typename UnaryFunction>
+ bool ApplyToTransceiver(const std::string& aId, UnaryFunction&& aFunction) {
+ for (auto& transceiver : GetTransceivers()) {
+ if (transceiver.GetUuid() == aId) {
+ std::forward<UnaryFunction>(aFunction)(transceiver);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ template <typename UnaryFunction>
+ void ForEachTransceiver(UnaryFunction&& aFunction) {
+ for (auto& transceiver : GetTransceivers()) {
+ std::forward<UnaryFunction>(aFunction)(transceiver);
+ }
+ }
+
+ template <typename UnaryFunction>
+ void ForEachTransceiver(UnaryFunction&& aFunction) const {
+ for (const auto& transceiver : GetTransceivers()) {
+ std::forward<UnaryFunction>(aFunction)(transceiver);
+ }
+ }
+
+ Maybe<const JsepTransceiver> GetTransceiver(const std::string& aId) const {
+ for (const auto& transceiver : GetTransceivers()) {
+ if (transceiver.GetUuid() == aId) {
+ return Some(transceiver);
+ }
+ }
+ return Nothing();
+ }
+
+ template <typename MatchFunction>
+ Maybe<const JsepTransceiver> FindTransceiver(MatchFunction&& aFunc) const {
+ for (const auto& transceiver : GetTransceivers()) {
+ if (std::forward<MatchFunction>(aFunc)(transceiver)) {
+ return Some(transceiver);
+ }
+ }
+ return Nothing();
+ }
+
+ bool SetTransceiver(const JsepTransceiver& aNew) {
+ return ApplyToTransceiver(aNew.GetUuid(),
+ [aNew](JsepTransceiver& aOld) { aOld = aNew; });
+ }
+
+ virtual void AddTransceiver(const JsepTransceiver& transceiver) = 0;
+
+ class Result {
+ public:
+ Result() = default;
+ MOZ_IMPLICIT Result(dom::PCError aError) : mError(Some(aError)) {}
+ // TODO(bug 1527916): Need c'tor and members for handling RTCError.
+ Maybe<dom::PCError> mError;
+ };
+
+ // Basic JSEP operations.
+ virtual Result CreateOffer(const JsepOfferOptions& options,
+ std::string* offer) = 0;
+ virtual Result CreateAnswer(const JsepAnswerOptions& options,
+ std::string* answer) = 0;
+ virtual std::string GetLocalDescription(
+ JsepDescriptionPendingOrCurrent type) const = 0;
+ virtual std::string GetRemoteDescription(
+ JsepDescriptionPendingOrCurrent type) const = 0;
+ virtual Result SetLocalDescription(JsepSdpType type,
+ const std::string& sdp) = 0;
+ virtual Result SetRemoteDescription(JsepSdpType type,
+ const std::string& sdp) = 0;
+ virtual Result AddRemoteIceCandidate(const std::string& candidate,
+ const std::string& mid,
+ const Maybe<uint16_t>& level,
+ const std::string& ufrag,
+ std::string* transportId) = 0;
+ virtual nsresult AddLocalIceCandidate(const std::string& candidate,
+ const std::string& transportId,
+ const std::string& ufrag,
+ uint16_t* level, std::string* mid,
+ bool* skipped) = 0;
+ virtual nsresult UpdateDefaultCandidate(
+ const std::string& defaultCandidateAddr, uint16_t defaultCandidatePort,
+ const std::string& defaultRtcpCandidateAddr,
+ uint16_t defaultRtcpCandidatePort, const std::string& transportId) = 0;
+ virtual nsresult Close() = 0;
+
+ // ICE controlling or controlled
+ virtual bool IsIceControlling() const = 0;
+ virtual Maybe<bool> IsPendingOfferer() const = 0;
+ virtual Maybe<bool> IsCurrentOfferer() const = 0;
+ virtual bool IsIceRestarting() const = 0;
+ virtual std::set<std::pair<std::string, std::string>> GetLocalIceCredentials()
+ const = 0;
+
+ virtual const std::string GetLastError() const { return "Error"; }
+
+ virtual const std::vector<std::pair<size_t, std::string>>&
+ GetLastSdpParsingErrors() const = 0;
+
+ static const char* GetStateStr(JsepSignalingState state) {
+ static const char* states[] = {"stable",
+ "have-local-offer",
+ "have-remote-offer",
+ "have-local-pranswer",
+ "have-remote-pranswer",
+ "closed"};
+
+ return states[state];
+ }
+
+ virtual bool CheckNegotiationNeeded() const = 0;
+
+ void CountTracksAndDatachannels(
+ uint16_t (&receiving)[SdpMediaSection::kMediaTypes],
+ uint16_t (&sending)[SdpMediaSection::kMediaTypes]) const {
+ memset(receiving, 0, sizeof(receiving));
+ memset(sending, 0, sizeof(sending));
+
+ for (const auto& transceiver : GetTransceivers()) {
+ if (transceiver.mRecvTrack.GetActive() ||
+ transceiver.GetMediaType() == SdpMediaSection::kApplication) {
+ receiving[transceiver.mRecvTrack.GetMediaType()]++;
+ }
+
+ if (transceiver.mSendTrack.GetActive() ||
+ transceiver.GetMediaType() == SdpMediaSection::kApplication) {
+ sending[transceiver.mSendTrack.GetMediaType()]++;
+ }
+ }
+ }
+
+ virtual void SetDefaultCodecs(
+ const std::vector<UniquePtr<JsepCodecDescription>>& aPreferredCodecs) = 0;
+
+ // See Bug 1642419, this can be removed when all sites are working with RTX.
+ void SetRtxIsAllowed(bool aRtxIsAllowed) { mRtxIsAllowed = aRtxIsAllowed; }
+
+ protected:
+ friend class JsepSessionTest;
+ // Returns transceivers in the order they were added.
+ virtual std::vector<JsepTransceiver>& GetTransceivers() = 0;
+ virtual const std::vector<JsepTransceiver>& GetTransceivers() const = 0;
+
+ const std::string mName;
+ JsepSignalingState mState;
+ uint32_t mNegotiations;
+
+ // See Bug 1642419, this can be removed when all sites are working with RTX.
+ bool mRtxIsAllowed = true;
+};
+
+} // namespace mozilla
+
+#endif