summaryrefslogtreecommitdiffstats
path: root/media/webrtc/signaling/src/jsep/JsepSessionImpl.h
blob: 00c07d25ed1fcedefbe97c4eb6a92f53693e3d26 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/* 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 <set>
#include <string>
#include <vector>

#include "signaling/src/jsep/JsepCodecDescription.h"
#include "signaling/src/jsep/JsepTrack.h"
#include "signaling/src/jsep/JsepSession.h"
#include "signaling/src/jsep/JsepTrack.h"
#include "signaling/src/sdp/SipccSdpParser.h"
#include "signaling/src/sdp/SdpHelper.h"
#include "signaling/src/common/PtrVector.h"

namespace mozilla {

class JsepUuidGenerator
{
public:
  virtual ~JsepUuidGenerator() {}
  virtual bool Generate(std::string* id) = 0;
};

class JsepSessionImpl : public JsepSession
{
public:
  JsepSessionImpl(const std::string& name, UniquePtr<JsepUuidGenerator> uuidgen)
      : JsepSession(name),
        mIsOfferer(false),
        mWasOffererLastTime(false),
        mIceControlling(false),
        mRemoteIsIceLite(false),
        mRemoteIceIsRestarting(false),
        mBundlePolicy(kBundleBalanced),
        mSessionId(0),
        mSessionVersion(0),
        mUuidGen(Move(uuidgen)),
        mSdpHelper(&mLastError)
  {
  }

  // Implement JsepSession methods.
  virtual nsresult Init() override;

  virtual nsresult AddTrack(const RefPtr<JsepTrack>& track) override;

  virtual nsresult RemoveTrack(const std::string& streamId,
                               const std::string& trackId) override;

  virtual nsresult SetIceCredentials(const std::string& ufrag,
                                     const std::string& pwd) override;
  virtual const std::string& GetUfrag() const override { return mIceUfrag; }
  virtual const std::string& GetPwd() const override { return mIcePwd; }
  nsresult SetBundlePolicy(JsepBundlePolicy policy) override;

  virtual bool
  RemoteIsIceLite() const override
  {
    return mRemoteIsIceLite;
  }

  virtual bool
  RemoteIceIsRestarting() const override
  {
    return mRemoteIceIsRestarting;
  }

  virtual std::vector<std::string>
  GetIceOptions() const override
  {
    return mIceOptions;
  }

  virtual nsresult AddDtlsFingerprint(const std::string& algorithm,
                                      const std::vector<uint8_t>& value) override;

  nsresult AddRtpExtension(std::vector<SdpExtmapAttributeList::Extmap>& extensions,
                           const std::string& extensionName,
                           SdpDirectionAttribute::Direction direction);
  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 std::vector<JsepCodecDescription*>&
  Codecs() override
  {
    return mSupportedCodecs.values;
  }

  virtual nsresult ReplaceTrack(const std::string& oldStreamId,
                                const std::string& oldTrackId,
                                const std::string& newStreamId,
                                const std::string& newTrackId) override;

  virtual nsresult SetParameters(
      const std::string& streamId,
      const std::string& trackId,
      const std::vector<JsepTrack::JsConstraints>& constraints) override;

  virtual nsresult GetParameters(
      const std::string& streamId,
      const std::string& trackId,
      std::vector<JsepTrack::JsConstraints>* outConstraints) override;

  virtual std::vector<RefPtr<JsepTrack>> GetLocalTracks() const override;

  virtual std::vector<RefPtr<JsepTrack>> GetRemoteTracks() const override;

  virtual std::vector<RefPtr<JsepTrack>>
    GetRemoteTracksAdded() const override;

  virtual std::vector<RefPtr<JsepTrack>>
    GetRemoteTracksRemoved() const override;

  virtual nsresult CreateOffer(const JsepOfferOptions& options,
                               std::string* offer) override;

  virtual nsresult CreateAnswer(const JsepAnswerOptions& options,
                                std::string* answer) override;

  virtual std::string GetLocalDescription() const override;

  virtual std::string GetRemoteDescription() const override;

  virtual nsresult SetLocalDescription(JsepSdpType type,
                                       const std::string& sdp) override;

  virtual nsresult SetRemoteDescription(JsepSdpType type,
                                        const std::string& sdp) override;

  virtual nsresult AddRemoteIceCandidate(const std::string& candidate,
                                         const std::string& mid,
                                         uint16_t level) override;

  virtual nsresult AddLocalIceCandidate(const std::string& candidate,
                                        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,
      uint16_t level) override;

  virtual nsresult EndOfLocalCandidates(uint16_t level) override;

  virtual nsresult Close() override;

  virtual const std::string GetLastError() const override;

  virtual bool
  IsIceControlling() const override
  {
    return mIceControlling;
  }

  virtual bool
  IsOfferer() const
  {
    return mIsOfferer;
  }

  // Access transports.
  virtual std::vector<RefPtr<JsepTransport>>
  GetTransports() const override
  {
    return mTransports;
  }

  virtual std::vector<JsepTrackPair>
  GetNegotiatedTrackPairs() const override
  {
    return mNegotiatedTrackPairs;
  }

  virtual bool AllLocalTracksAreAssigned() const override;

private:
  struct JsepDtlsFingerprint {
    std::string mAlgorithm;
    std::vector<uint8_t> mValue;
  };

  struct JsepSendingTrack {
    RefPtr<JsepTrack> mTrack;
    Maybe<size_t> mAssignedMLine;
  };

  struct JsepReceivingTrack {
    RefPtr<JsepTrack> mTrack;
    Maybe<size_t> mAssignedMLine;
  };

  // Non-const so it can set mLastError
  nsresult CreateGenericSDP(UniquePtr<Sdp>* sdp);
  void AddExtmap(SdpMediaSection* msection) const;
  void AddMid(const std::string& mid, SdpMediaSection* msection) const;
  const std::vector<SdpExtmapAttributeList::Extmap>* GetRtpExtensions(
      SdpMediaSection::MediaType type) const;

  void AddCommonExtmaps(const SdpMediaSection& remoteMsection,
                        SdpMediaSection* msection);
  nsresult SetupIds();
  nsresult CreateSsrc(uint32_t* ssrc);
  void SetupDefaultCodecs();
  void SetupDefaultRtpExtensions();
  void SetState(JsepSignalingState state);
  // Non-const so it can set mLastError
  nsresult ParseSdp(const std::string& sdp, UniquePtr<Sdp>* parsedp);
  nsresult SetLocalDescriptionOffer(UniquePtr<Sdp> offer);
  nsresult SetLocalDescriptionAnswer(JsepSdpType type, UniquePtr<Sdp> answer);
  nsresult SetRemoteDescriptionOffer(UniquePtr<Sdp> offer);
  nsresult SetRemoteDescriptionAnswer(JsepSdpType type, UniquePtr<Sdp> answer);
  nsresult ValidateLocalDescription(const Sdp& description);
  nsresult ValidateRemoteDescription(const Sdp& description);
  nsresult ValidateAnswer(const Sdp& offer, const Sdp& answer);
  nsresult SetRemoteTracksFromDescription(const Sdp* remoteDescription);
  // Non-const because we use our Uuid generator
  nsresult CreateReceivingTrack(size_t mline,
                                const Sdp& sdp,
                                const SdpMediaSection& msection,
                                RefPtr<JsepTrack>* track);
  nsresult HandleNegotiatedSession(const UniquePtr<Sdp>& local,
                                   const UniquePtr<Sdp>& remote);
  nsresult AddTransportAttributes(SdpMediaSection* msection,
                                  SdpSetupAttribute::Role dtlsRole);
  nsresult CopyPreviousTransportParams(const Sdp& oldAnswer,
                                       const Sdp& offerersPreviousSdp,
                                       const Sdp& newOffer,
                                       Sdp* newLocal);
  nsresult SetupOfferMSections(const JsepOfferOptions& options, Sdp* sdp);
  // Non-const so it can assign m-line index to tracks
  nsresult SetupOfferMSectionsByType(SdpMediaSection::MediaType type,
                                     Maybe<size_t> offerToReceive,
                                     Sdp* sdp);
  nsresult BindLocalTracks(SdpMediaSection::MediaType mediatype,
                           Sdp* sdp);
  nsresult BindRemoteTracks(SdpMediaSection::MediaType mediatype,
                            Sdp* sdp,
                            size_t* offerToReceive);
  nsresult SetRecvAsNeededOrDisable(SdpMediaSection::MediaType mediatype,
                                    Sdp* sdp,
                                    size_t* offerToRecv);
  void SetupOfferToReceiveMsection(SdpMediaSection* offer);
  nsresult AddRecvonlyMsections(SdpMediaSection::MediaType mediatype,
                                size_t count,
                                Sdp* sdp);
  nsresult AddReofferMsections(const Sdp& oldLocalSdp,
                               const Sdp& oldAnswer,
                               Sdp* newSdp);
  void SetupBundle(Sdp* sdp) const;
  nsresult GetRemoteIds(const Sdp& sdp,
                        const SdpMediaSection& msection,
                        std::string* streamId,
                        std::string* trackId);
  nsresult CreateOfferMSection(SdpMediaSection::MediaType type,
                               SdpMediaSection::Protocol proto,
                               SdpDirectionAttribute::Direction direction,
                               Sdp* sdp);
  nsresult GetFreeMsectionForSend(SdpMediaSection::MediaType type,
                                  Sdp* sdp,
                                  SdpMediaSection** msection);
  nsresult CreateAnswerMSection(const JsepAnswerOptions& options,
                                size_t mlineIndex,
                                const SdpMediaSection& remoteMsection,
                                Sdp* sdp);
  nsresult SetRecvonlySsrc(SdpMediaSection* msection);
  nsresult BindMatchingLocalTrackToAnswer(SdpMediaSection* msection);
  nsresult BindMatchingRemoteTrackToAnswer(SdpMediaSection* msection);
  nsresult DetermineAnswererSetupRole(const SdpMediaSection& remoteMsection,
                                      SdpSetupAttribute::Role* rolep);
  nsresult MakeNegotiatedTrackPair(const SdpMediaSection& remote,
                                   const SdpMediaSection& local,
                                   const RefPtr<JsepTransport>& transport,
                                   bool usingBundle,
                                   size_t transportLevel,
                                   JsepTrackPair* trackPairOut);
  void InitTransport(const SdpMediaSection& msection, JsepTransport* transport);

  nsresult FinalizeTransport(const SdpAttributeList& remote,
                             const SdpAttributeList& answer,
                             const RefPtr<JsepTransport>& transport);

  nsresult GetNegotiatedBundledMids(SdpHelper::BundledMids* bundledMids);

  nsresult EnableOfferMsection(SdpMediaSection* msection);

  mozilla::Sdp* GetParsedLocalDescription() const;
  mozilla::Sdp* GetParsedRemoteDescription() const;
  const Sdp* GetAnswer() const;

  std::vector<JsepSendingTrack> mLocalTracks;
  std::vector<JsepReceivingTrack> mRemoteTracks;
  // By the most recent SetRemoteDescription
  std::vector<JsepReceivingTrack> mRemoteTracksAdded;
  std::vector<JsepReceivingTrack> mRemoteTracksRemoved;
  std::vector<RefPtr<JsepTransport> > mTransports;
  // So we can rollback
  std::vector<RefPtr<JsepTransport> > mOldTransports;
  std::vector<JsepTrackPair> mNegotiatedTrackPairs;

  bool mIsOfferer;
  bool mWasOffererLastTime;
  bool mIceControlling;
  std::string mIceUfrag;
  std::string mIcePwd;
  bool mRemoteIsIceLite;
  bool mRemoteIceIsRestarting;
  std::vector<std::string> mIceOptions;
  JsepBundlePolicy mBundlePolicy;
  std::vector<JsepDtlsFingerprint> mDtlsFingerprints;
  uint64_t mSessionId;
  uint64_t mSessionVersion;
  std::vector<SdpExtmapAttributeList::Extmap> mAudioRtpExtensions;
  std::vector<SdpExtmapAttributeList::Extmap> mVideoRtpExtensions;
  UniquePtr<JsepUuidGenerator> mUuidGen;
  std::string mDefaultRemoteStreamId;
  std::map<size_t, std::string> mDefaultRemoteTrackIdsByLevel;
  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<uint32_t> mSsrcs;
  // When an m-section doesn't have a local track, it still needs an ssrc, which
  // is stored here.
  std::vector<uint32_t> mRecvonlySsrcs;
  UniquePtr<Sdp> mGeneratedLocalDescription; // Created but not set.
  UniquePtr<Sdp> mCurrentLocalDescription;
  UniquePtr<Sdp> mCurrentRemoteDescription;
  UniquePtr<Sdp> mPendingLocalDescription;
  UniquePtr<Sdp> mPendingRemoteDescription;
  PtrVector<JsepCodecDescription> mSupportedCodecs;
  std::string mLastError;
  SipccSdpParser mParser;
  SdpHelper mSdpHelper;
};

} // namespace mozilla

#endif