Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/media/webrtc/signaling/src/sdp/RsdparsaSdpMediaSection.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5
 * You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "signaling/src/sdp/SdpMediaSection.h"
8
#include "signaling/src/sdp/RsdparsaSdpMediaSection.h"
9
10
#include "signaling/src/sdp/RsdparsaSdpGlue.h"
11
#include "signaling/src/sdp/RsdparsaSdpInc.h"
12
13
#include <ostream>
14
#include "signaling/src/sdp/SdpErrorHolder.h"
15
16
#ifdef CRLF
17
#undef CRLF
18
#endif
19
0
#define CRLF "\r\n"
20
21
namespace mozilla
22
{
23
24
RsdparsaSdpMediaSection::RsdparsaSdpMediaSection(size_t level,
25
      RsdparsaSessionHandle session, const RustMediaSection* const section,
26
      const RsdparsaSdpAttributeList* sessionLevel)
27
  : SdpMediaSection(level), mSession(std::move(session)),
28
    mSection(section)
29
0
{
30
0
  switch(sdp_rust_get_media_type(section)) {
31
0
    case RustSdpMediaValue::kRustAudio:
32
0
      mMediaType = kAudio;
33
0
      break;
34
0
    case RustSdpMediaValue::kRustVideo:
35
0
      mMediaType = kVideo;
36
0
      break;
37
0
    case RustSdpMediaValue::kRustApplication:
38
0
      mMediaType = kApplication;
39
0
      break;
40
0
  }
41
0
42
0
  RsdparsaSessionHandle attributeSession(sdp_new_reference(mSession.get()));
43
0
  mAttributeList.reset(new RsdparsaSdpAttributeList(std::move(attributeSession),
44
0
                                                    section,
45
0
                                                    sessionLevel));
46
0
47
0
  LoadFormats();
48
0
  LoadConnection();
49
0
}
50
51
unsigned int
52
RsdparsaSdpMediaSection::GetPort() const
53
0
{
54
0
  return sdp_get_media_port(mSection);
55
0
}
56
57
void
58
RsdparsaSdpMediaSection::SetPort(unsigned int port)
59
0
{
60
0
  sdp_set_media_port(mSection, port);
61
0
}
62
63
unsigned int
64
RsdparsaSdpMediaSection::GetPortCount() const
65
0
{
66
0
  return sdp_get_media_port_count(mSection);
67
0
}
68
69
SdpMediaSection::Protocol
70
RsdparsaSdpMediaSection::GetProtocol() const
71
0
{
72
0
  switch(sdp_get_media_protocol(mSection)) {
73
0
    case RustSdpProtocolValue::kRustRtpSavpf:
74
0
      return kRtpSavpf;
75
0
    case RustSdpProtocolValue::kRustUdpTlsRtpSavpf:
76
0
      return kUdpTlsRtpSavpf;
77
0
    case RustSdpProtocolValue::kRustTcpTlsRtpSavpf:
78
0
      return kTcpTlsRtpSavpf;
79
0
    case RustSdpProtocolValue::kRustDtlsSctp:
80
0
      return kDtlsSctp;
81
0
    case RustSdpProtocolValue::kRustUdpDtlsSctp:
82
0
      return kUdpDtlsSctp;
83
0
    case RustSdpProtocolValue::kRustTcpDtlsSctp:
84
0
      return kTcpDtlsSctp;
85
0
  }
86
0
87
0
  MOZ_CRASH("invalid media protocol");
88
0
}
89
90
const SdpConnection&
91
RsdparsaSdpMediaSection::GetConnection() const
92
0
{
93
0
  MOZ_ASSERT(mConnection);
94
0
  return *mConnection;
95
0
}
96
97
SdpConnection&
98
RsdparsaSdpMediaSection::GetConnection()
99
0
{
100
0
  MOZ_ASSERT(mConnection);
101
0
  return *mConnection;
102
0
}
103
104
uint32_t
105
RsdparsaSdpMediaSection::GetBandwidth(const std::string& type) const
106
0
{
107
0
  return sdp_get_media_bandwidth(mSection, type.c_str());
108
0
}
109
110
const std::vector<std::string>&
111
RsdparsaSdpMediaSection::GetFormats() const
112
0
{
113
0
  return mFormats;
114
0
}
115
116
const SdpAttributeList&
117
RsdparsaSdpMediaSection::GetAttributeList() const
118
0
{
119
0
  return *mAttributeList;
120
0
}
121
122
SdpAttributeList&
123
RsdparsaSdpMediaSection::GetAttributeList()
124
0
{
125
0
  return *mAttributeList;
126
0
}
127
128
SdpDirectionAttribute
129
RsdparsaSdpMediaSection::GetDirectionAttribute() const
130
0
{
131
0
  return SdpDirectionAttribute(mAttributeList->GetDirection());
132
0
}
133
134
void
135
RsdparsaSdpMediaSection::AddCodec(const std::string& pt,
136
                                  const std::string& name,
137
                                  uint32_t clockrate, uint16_t channels)
138
0
{
139
0
  StringView rustName{name.c_str(),name.size()};
140
0
141
0
  // call the rust interface
142
0
  auto nr = sdp_media_add_codec(mSection, std::stoul(pt),rustName,clockrate,channels);
143
0
144
0
  if (NS_SUCCEEDED(nr)) {
145
0
    // If the rust call was successful, adjust the shadow C++ structures
146
0
    mFormats.push_back(pt);
147
0
148
0
    // Add a rtpmap in mAttributeList
149
0
    SdpRtpmapAttributeList* rtpmap = new SdpRtpmapAttributeList();
150
0
    if (mAttributeList->HasAttribute(SdpAttribute::kRtpmapAttribute)) {
151
0
      const SdpRtpmapAttributeList& old = mAttributeList->GetRtpmap();
152
0
      for (auto it = old.mRtpmaps.begin(); it != old.mRtpmaps.end(); ++it) {
153
0
        rtpmap->mRtpmaps.push_back(*it);
154
0
      }
155
0
    }
156
0
157
0
    SdpRtpmapAttributeList::CodecType codec = SdpRtpmapAttributeList::kOtherCodec;
158
0
    if (name == "opus") {
159
0
      codec = SdpRtpmapAttributeList::kOpus;
160
0
    } else if (name == "VP8") {
161
0
      codec = SdpRtpmapAttributeList::kVP8;
162
0
    } else if (name == "VP9") {
163
0
      codec = SdpRtpmapAttributeList::kVP9;
164
0
    } else if (name == "H264") {
165
0
      codec = SdpRtpmapAttributeList::kH264;
166
0
    }
167
0
168
0
    rtpmap->PushEntry(pt, codec, name, clockrate, channels);
169
0
    mAttributeList->SetAttribute(rtpmap);
170
0
  }
171
0
172
0
}
173
174
void
175
RsdparsaSdpMediaSection::ClearCodecs()
176
0
{
177
0
  // Clear the codecs in rust
178
0
  sdp_media_clear_codecs(mSection);
179
0
180
0
  mFormats.clear();
181
0
  mAttributeList->RemoveAttribute(SdpAttribute::kRtpmapAttribute);
182
0
  mAttributeList->RemoveAttribute(SdpAttribute::kFmtpAttribute);
183
0
  mAttributeList->RemoveAttribute(SdpAttribute::kSctpmapAttribute);
184
0
  mAttributeList->RemoveAttribute(SdpAttribute::kRtcpFbAttribute);
185
0
}
186
187
void
188
RsdparsaSdpMediaSection::AddDataChannel(const std::string& name, uint16_t port,
189
                                        uint16_t streams, uint32_t message_size)
190
0
{
191
0
  StringView rustName{name.c_str(), name.size()};
192
0
  auto nr = sdp_media_add_datachannel(mSection, rustName, port,
193
0
                                      streams, message_size);
194
0
  if (NS_SUCCEEDED(nr)) {
195
0
    // Update the formats
196
0
    mFormats.clear();
197
0
    LoadFormats();
198
0
199
0
    // Update the attribute list
200
0
    RsdparsaSessionHandle sessHandle(sdp_new_reference(mSession.get()));
201
0
    auto sessAttributes = mAttributeList->mSessionAttributes;
202
0
    mAttributeList.reset(new RsdparsaSdpAttributeList(std::move(sessHandle),
203
0
                                                      mSection,
204
0
                                                      sessAttributes));
205
0
  }
206
0
}
207
208
void
209
RsdparsaSdpMediaSection::Serialize(std::ostream& os) const
210
0
{
211
0
  os << "m=" << mMediaType << " " << GetPort();
212
0
  if (GetPortCount()) {
213
0
    os << "/" << GetPortCount();
214
0
  }
215
0
  os << " " << GetProtocol();
216
0
  for (auto i = mFormats.begin(); i != mFormats.end(); ++i) {
217
0
    os << " " << (*i);
218
0
  }
219
0
  os << CRLF;
220
0
221
0
  // We dont do i=
222
0
223
0
  if (mConnection) {
224
0
    os << *mConnection;
225
0
  }
226
0
227
0
  BandwidthVec* bwVec = sdp_get_media_bandwidth_vec(mSection);
228
0
  char* bwString = sdp_serialize_bandwidth(bwVec);
229
0
  if (bwString) {
230
0
    os << bwString;
231
0
    sdp_free_string(bwString);
232
0
  }
233
0
234
0
  // We dont do k= because they're evil
235
0
236
0
  os << *mAttributeList;
237
0
}
238
239
void
240
RsdparsaSdpMediaSection::LoadFormats()
241
0
{
242
0
  RustSdpFormatType formatType = sdp_get_format_type(mSection);
243
0
  if (formatType == RustSdpFormatType::kRustIntegers) {
244
0
    U32Vec* vec = sdp_get_format_u32_vec(mSection);
245
0
    size_t len = u32_vec_len(vec);
246
0
    for (size_t i = 0; i < len; i++) {
247
0
      uint32_t val;
248
0
      u32_vec_get(vec, i, &val);
249
0
      mFormats.push_back(std::to_string(val));
250
0
    }
251
0
  } else {
252
0
    StringVec* vec = sdp_get_format_string_vec(mSection);
253
0
    mFormats = convertStringVec(vec);
254
0
  }
255
0
}
256
257
UniquePtr<SdpConnection> convertRustConnection(RustSdpConnection conn)
258
0
{
259
0
  std::string addr(conn.addr.unicastAddr);
260
0
  sdp::AddrType type = convertAddressType(conn.addr.addrType);
261
0
  return MakeUnique<SdpConnection>(type, addr, conn.ttl, conn.amount);
262
0
}
263
264
void
265
RsdparsaSdpMediaSection::LoadConnection()
266
0
{
267
0
  RustSdpConnection conn;
268
0
  nsresult nr;
269
0
  if (sdp_media_has_connection(mSection)) {
270
0
    nr = sdp_get_media_connection(mSection, &conn);
271
0
    if (NS_SUCCEEDED(nr)) {
272
0
      mConnection = convertRustConnection(conn);
273
0
    }
274
0
  } else if (sdp_session_has_connection(mSession.get())){
275
0
    nr = sdp_get_session_connection(mSession.get(), &conn);
276
0
    if (NS_SUCCEEDED(nr)) {
277
0
      mConnection = convertRustConnection(conn);
278
0
    }
279
0
  }
280
0
}
281
282
} // namespace mozilla