Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/media/webrtc/signaling/gtest/sdp_unittests.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 "timecard.h"
8
9
#include <string>
10
#include <sstream>
11
12
#define GTEST_HAS_RTTI 0
13
#include "gtest/gtest.h"
14
15
#include "nspr.h"
16
#include "nss.h"
17
#include "ssl.h"
18
19
#include "nsThreadUtils.h"
20
21
#include "signaling/src/sdp/RsdparsaSdpParser.h"
22
#include "signaling/src/sdp/SipccSdpParser.h"
23
#include "signaling/src/sdp/SdpMediaSection.h"
24
#include "signaling/src/sdp/SdpAttribute.h"
25
#include "signaling/src/sdp/ParsingResultComparer.h"
26
27
extern "C" {
28
#include "signaling/src/sdp/sipcc/sdp.h"
29
#include "signaling/src/sdp/sipcc/sdp_private.h"
30
}
31
32
#ifdef CRLF
33
#undef CRLF
34
#endif
35
0
#define CRLF "\r\n"
36
37
#define SKIP_TEST_WITH_RUST_PARSER if (!::testing::get<1>(GetParam())) {return;}
38
0
#define SKIP_TEST_WITH_SIPCC_PARSER if (IsParsingWithSipccParser()) {return;}
39
40
using namespace mozilla;
41
42
namespace test {
43
44
class SdpTest : public ::testing::Test {
45
  public:
46
    SdpTest()
47
      : final_level_(0)
48
0
      , sdp_ptr_(nullptr) {
49
0
    }
50
51
0
    ~SdpTest() {
52
0
      sdp_free_description(sdp_ptr_);
53
0
    }
54
55
0
    static void SetUpTestCase() {
56
0
      NSS_NoDB_Init(nullptr);
57
0
      NSS_SetDomesticPolicy();
58
0
    }
59
60
0
    void SetUp() {
61
0
      final_level_ = 0;
62
0
      sdp_ptr_ = nullptr;
63
0
    }
64
65
0
    static void TearDownTestCase() {
66
0
    }
67
68
0
    void ResetSdp() {
69
0
      if (!sdp_ptr_) {
70
0
        sdp_free_description(sdp_ptr_);
71
0
      }
72
0
73
0
      sdp_media_e supported_media[] = {
74
0
        SDP_MEDIA_AUDIO,
75
0
        SDP_MEDIA_VIDEO,
76
0
        SDP_MEDIA_APPLICATION,
77
0
        SDP_MEDIA_DATA,
78
0
        SDP_MEDIA_CONTROL,
79
0
        SDP_MEDIA_NAS_RADIUS,
80
0
        SDP_MEDIA_NAS_TACACS,
81
0
        SDP_MEDIA_NAS_DIAMETER,
82
0
        SDP_MEDIA_NAS_L2TP,
83
0
        SDP_MEDIA_NAS_LOGIN,
84
0
        SDP_MEDIA_NAS_NONE,
85
0
        SDP_MEDIA_IMAGE,
86
0
      };
87
0
88
0
      sdp_conf_options_t *config_p = sdp_init_config();
89
0
      unsigned int i;
90
0
      for (i = 0; i < sizeof(supported_media) / sizeof(sdp_media_e); i++) {
91
0
        sdp_media_supported(config_p, supported_media[i], true);
92
0
      }
93
0
      sdp_nettype_supported(config_p, SDP_NT_INTERNET, true);
94
0
      sdp_addrtype_supported(config_p, SDP_AT_IP4, true);
95
0
      sdp_addrtype_supported(config_p, SDP_AT_IP6, true);
96
0
      sdp_transport_supported(config_p, SDP_TRANSPORT_RTPSAVPF, true);
97
0
      sdp_transport_supported(config_p, SDP_TRANSPORT_UDPTL, true);
98
0
      sdp_require_session_name(config_p, false);
99
0
100
0
      sdp_ptr_ = sdp_init_description(config_p);
101
0
      if (!sdp_ptr_) {
102
0
        sdp_free_config(config_p);
103
0
      }
104
0
    }
105
106
0
    void ParseSdp(const std::string &sdp_str) {
107
0
      const char *buf = sdp_str.data();
108
0
      ResetSdp();
109
0
      ASSERT_EQ(sdp_parse(sdp_ptr_, buf, sdp_str.size()), SDP_SUCCESS);
110
0
    }
111
112
0
    void InitLocalSdp() {
113
0
      ResetSdp();
114
0
      ASSERT_EQ(sdp_set_version(sdp_ptr_, 0), SDP_SUCCESS);
115
0
      ASSERT_EQ(sdp_set_owner_username(sdp_ptr_, "-"), SDP_SUCCESS);
116
0
      ASSERT_EQ(sdp_set_owner_sessionid(sdp_ptr_, "132954853"), SDP_SUCCESS);
117
0
      ASSERT_EQ(sdp_set_owner_version(sdp_ptr_, "0"), SDP_SUCCESS);
118
0
      ASSERT_EQ(sdp_set_owner_network_type(sdp_ptr_, SDP_NT_INTERNET),
119
0
                SDP_SUCCESS);
120
0
      ASSERT_EQ(sdp_set_owner_address_type(sdp_ptr_, SDP_AT_IP4), SDP_SUCCESS);
121
0
      ASSERT_EQ(sdp_set_owner_address(sdp_ptr_, "198.51.100.7"), SDP_SUCCESS);
122
0
      ASSERT_EQ(sdp_set_session_name(sdp_ptr_, "SDP Unit Test"), SDP_SUCCESS);
123
0
      ASSERT_EQ(sdp_set_time_start(sdp_ptr_, "0"), SDP_SUCCESS);
124
0
      ASSERT_EQ(sdp_set_time_stop(sdp_ptr_, "0"), SDP_SUCCESS);
125
0
    }
126
127
0
    std::string SerializeSdp() {
128
0
      flex_string fs;
129
0
      flex_string_init(&fs);
130
0
      EXPECT_EQ(sdp_build(sdp_ptr_, &fs), SDP_SUCCESS);
131
0
      std::string body(fs.buffer);
132
0
      flex_string_free(&fs);
133
0
      return body;
134
0
    }
135
136
    // Returns "level" for new media section
137
0
    int AddNewMedia(sdp_media_e type) {
138
0
      final_level_++;
139
0
      EXPECT_EQ(sdp_insert_media_line(sdp_ptr_, final_level_), SDP_SUCCESS);
140
0
      EXPECT_EQ(sdp_set_conn_nettype(sdp_ptr_, final_level_, SDP_NT_INTERNET),
141
0
                SDP_SUCCESS);
142
0
      EXPECT_EQ(sdp_set_conn_addrtype(sdp_ptr_, final_level_, SDP_AT_IP4),
143
0
                SDP_SUCCESS);
144
0
      EXPECT_EQ(sdp_set_conn_address(sdp_ptr_, final_level_, "198.51.100.7"),
145
0
                SDP_SUCCESS);
146
0
      EXPECT_EQ(sdp_set_media_type(sdp_ptr_, final_level_, SDP_MEDIA_VIDEO),
147
0
                SDP_SUCCESS);
148
0
      EXPECT_EQ(sdp_set_media_transport(sdp_ptr_, final_level_,
149
0
                                        SDP_TRANSPORT_RTPAVP),
150
0
                SDP_SUCCESS);
151
0
      EXPECT_EQ(sdp_set_media_portnum(sdp_ptr_, final_level_, 12345, 0),
152
0
                SDP_SUCCESS);
153
0
      EXPECT_EQ(sdp_add_media_payload_type(sdp_ptr_, final_level_, 120,
154
0
                                           SDP_PAYLOAD_NUMERIC),
155
0
                SDP_SUCCESS);
156
0
      return final_level_;
157
0
    }
158
159
    uint16_t AddNewRtcpFbAck(int level, sdp_rtcp_fb_ack_type_e type,
160
0
                         uint16_t payload = SDP_ALL_PAYLOADS) {
161
0
      uint16_t inst_num = 0;
162
0
      EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
163
0
                                 &inst_num), SDP_SUCCESS);
164
0
      EXPECT_EQ(sdp_attr_set_rtcp_fb_ack(sdp_ptr_, level, payload, inst_num,
165
0
                                         type), SDP_SUCCESS);
166
0
      return inst_num;
167
0
    }
168
169
    uint16_t AddNewRtcpFbNack(int level, sdp_rtcp_fb_nack_type_e type,
170
0
                         uint16_t payload = SDP_ALL_PAYLOADS) {
171
0
      uint16_t inst_num = 0;
172
0
      EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
173
0
                                 &inst_num), SDP_SUCCESS);
174
0
      EXPECT_EQ(sdp_attr_set_rtcp_fb_nack(sdp_ptr_, level, payload, inst_num,
175
0
                                          type), SDP_SUCCESS);
176
0
      return inst_num;
177
0
    }
178
179
    uint16_t AddNewRtcpFbTrrInt(int level, uint32_t interval,
180
0
                         uint16_t payload = SDP_ALL_PAYLOADS) {
181
0
      uint16_t inst_num = 0;
182
0
      EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
183
0
                                 &inst_num), SDP_SUCCESS);
184
0
      EXPECT_EQ(sdp_attr_set_rtcp_fb_trr_int(sdp_ptr_, level, payload, inst_num,
185
0
                                             interval), SDP_SUCCESS);
186
0
      return inst_num;
187
0
    }
188
189
    uint16_t AddNewRtcpFbRemb(int level,
190
0
                              uint16_t payload = SDP_ALL_PAYLOADS) {
191
0
      uint16_t inst_num = 0;
192
0
      EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
193
0
                                 &inst_num), SDP_SUCCESS);
194
0
      EXPECT_EQ(sdp_attr_set_rtcp_fb_remb(sdp_ptr_, level, payload, inst_num
195
0
                                          ), SDP_SUCCESS);
196
0
      return inst_num;
197
0
    }
198
199
    uint16_t AddNewRtcpFbCcm(int level, sdp_rtcp_fb_ccm_type_e type,
200
0
                         uint16_t payload = SDP_ALL_PAYLOADS) {
201
0
      uint16_t inst_num = 0;
202
0
      EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_RTCP_FB,
203
0
                                 &inst_num), SDP_SUCCESS);
204
0
      EXPECT_EQ(sdp_attr_set_rtcp_fb_ccm(sdp_ptr_, level, payload, inst_num,
205
0
                                         type), SDP_SUCCESS);
206
0
      return inst_num;
207
0
    }
208
0
    uint16_t AddNewExtMap(int level, const char* uri) {
209
0
      uint16_t inst_num = 0;
210
0
      EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_EXTMAP,
211
0
                                 &inst_num), SDP_SUCCESS);
212
0
      EXPECT_EQ(sdp_attr_set_extmap(sdp_ptr_, level, inst_num,
213
0
                                    uri, inst_num), SDP_SUCCESS);
214
0
      return inst_num;
215
0
    }
216
217
0
    uint16_t AddNewFmtpMaxFs(int level, uint32_t max_fs) {
218
0
      uint16_t inst_num = 0;
219
0
      EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_FMTP,
220
0
                                 &inst_num), SDP_SUCCESS);
221
0
      EXPECT_EQ(sdp_attr_set_fmtp_payload_type(sdp_ptr_, level, 0, inst_num,
222
0
                                               120), SDP_SUCCESS);
223
0
      EXPECT_EQ(sdp_attr_set_fmtp_max_fs(sdp_ptr_, level, 0, inst_num, max_fs),
224
0
                                         SDP_SUCCESS);
225
0
      return inst_num;
226
0
    }
227
228
0
    uint16_t AddNewFmtpMaxFr(int level, uint32_t max_fr) {
229
0
      uint16_t inst_num = 0;
230
0
      EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_FMTP,
231
0
                                 &inst_num), SDP_SUCCESS);
232
0
      EXPECT_EQ(sdp_attr_set_fmtp_payload_type(sdp_ptr_, level, 0, inst_num,
233
0
                                               120), SDP_SUCCESS);
234
0
      EXPECT_EQ(sdp_attr_set_fmtp_max_fr(sdp_ptr_, level, 0, inst_num, max_fr),
235
0
                                         SDP_SUCCESS);
236
0
      return inst_num;
237
0
    }
238
239
0
     uint16_t AddNewFmtpMaxFsFr(int level, uint32_t max_fs, uint32_t max_fr) {
240
0
      uint16_t inst_num = 0;
241
0
      EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, level, 0, SDP_ATTR_FMTP,
242
0
                                 &inst_num), SDP_SUCCESS);
243
0
      EXPECT_EQ(sdp_attr_set_fmtp_payload_type(sdp_ptr_, level, 0, inst_num,
244
0
                                               120), SDP_SUCCESS);
245
0
      EXPECT_EQ(sdp_attr_set_fmtp_max_fs(sdp_ptr_, level, 0, inst_num, max_fs),
246
0
                                         SDP_SUCCESS);
247
0
      EXPECT_EQ(sdp_attr_set_fmtp_max_fr(sdp_ptr_, level, 0, inst_num, max_fr),
248
0
                                         SDP_SUCCESS);
249
0
      return inst_num;
250
0
    }
251
252
  protected:
253
    int final_level_;
254
    sdp_t *sdp_ptr_;
255
};
256
257
static const std::string kVideoSdp =
258
  "v=0\r\n"
259
  "o=- 4294967296 2 IN IP4 127.0.0.1\r\n"
260
  "s=SIP Call\r\n"
261
  "c=IN IP4 198.51.100.7\r\n"
262
  "t=0 0\r\n"
263
  "m=video 56436 RTP/SAVPF 120\r\n"
264
  "a=rtpmap:120 VP8/90000\r\n";
265
266
0
TEST_F(SdpTest, parseRtcpFbAckRpsi) {
267
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack rpsi\r\n");
268
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1),
269
0
            SDP_RTCP_FB_ACK_RPSI);
270
0
}
271
272
0
TEST_F(SdpTest, parseRtcpFbAckApp) {
273
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack app\r\n");
274
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_ACK_APP);
275
0
}
276
277
0
TEST_F(SdpTest, parseRtcpFbAckAppFoo) {
278
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack app foo\r\n");
279
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_ACK_APP);
280
0
}
281
282
0
TEST_F(SdpTest, parseRtcpFbAckFooBar) {
283
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack foo bar\r\n");
284
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1),
285
0
            SDP_RTCP_FB_ACK_UNKNOWN);
286
0
}
287
288
0
TEST_F(SdpTest, parseRtcpFbAckFooBarBaz) {
289
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ack foo bar baz\r\n");
290
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1),
291
0
            SDP_RTCP_FB_ACK_UNKNOWN);
292
0
}
293
294
0
TEST_F(SdpTest, parseRtcpFbNack) {
295
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack\r\n");
296
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
297
0
            SDP_RTCP_FB_NACK_BASIC);
298
0
}
299
300
0
TEST_F(SdpTest, parseRtcpFbNackPli) {
301
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack pli\r\n");
302
0
}
303
304
0
TEST_F(SdpTest, parseRtcpFbNackSli) {
305
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack sli\r\n");
306
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
307
0
            SDP_RTCP_FB_NACK_SLI);
308
0
}
309
310
0
TEST_F(SdpTest, parseRtcpFbNackRpsi) {
311
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack rpsi\r\n");
312
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
313
0
            SDP_RTCP_FB_NACK_RPSI);
314
0
}
315
316
0
TEST_F(SdpTest, parseRtcpFbNackApp) {
317
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack app\r\n");
318
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
319
0
            SDP_RTCP_FB_NACK_APP);
320
0
}
321
322
0
TEST_F(SdpTest, parseRtcpFbNackAppFoo) {
323
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack app foo\r\n");
324
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
325
0
            SDP_RTCP_FB_NACK_APP);
326
0
}
327
328
0
TEST_F(SdpTest, parseRtcpFbNackAppFooBar) {
329
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack app foo bar\r\n");
330
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
331
0
            SDP_RTCP_FB_NACK_APP);
332
0
}
333
334
0
TEST_F(SdpTest, parseRtcpFbNackFooBarBaz) {
335
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 nack foo bar baz\r\n");
336
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
337
0
            SDP_RTCP_FB_NACK_UNKNOWN);
338
0
}
339
340
0
TEST_F(SdpTest, parseRtcpFbRemb) {
341
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 goog-remb\r\n");
342
0
  ASSERT_EQ((bool)sdp_attr_get_rtcp_fb_remb_enabled(sdp_ptr_, 1, 120), true);
343
0
}
344
345
0
TEST_F(SdpTest, parseRtcpRbRembAllPt) {
346
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:* goog-remb\r\n");
347
0
  ASSERT_EQ((bool)sdp_attr_get_rtcp_fb_remb_enabled(sdp_ptr_, 1, SDP_ALL_PAYLOADS),
348
0
                                                    true);
349
0
}
350
351
0
TEST_F(SdpTest, parseRtcpFbTrrInt0) {
352
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 trr-int 0\r\n");
353
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 1), 0U);
354
0
}
355
356
0
TEST_F(SdpTest, parseRtcpFbTrrInt123) {
357
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 trr-int 123\r\n");
358
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 1), 123U);
359
0
}
360
361
0
TEST_F(SdpTest, parseRtcpFbCcmFir) {
362
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm fir\r\n");
363
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_CCM_FIR);
364
0
}
365
366
0
TEST_F(SdpTest, parseRtcpFbCcmTmmbr) {
367
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm tmmbr\r\n");
368
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
369
0
            SDP_RTCP_FB_CCM_TMMBR);
370
0
}
371
372
0
TEST_F(SdpTest, parseRtcpFbCcmTmmbrSmaxpr) {
373
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm tmmbr smaxpr=456\r\n");
374
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
375
0
            SDP_RTCP_FB_CCM_TMMBR);
376
0
}
377
378
0
TEST_F(SdpTest, parseRtcpFbCcmTstr) {
379
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm tstr\r\n");
380
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
381
0
            SDP_RTCP_FB_CCM_TSTR);
382
0
}
383
384
0
TEST_F(SdpTest, parseRtcpFbCcmVbcm) {
385
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm vbcm 123 456 789\r\n");
386
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
387
0
                                     SDP_RTCP_FB_CCM_VBCM);
388
0
  // We don't currently parse out VBCM submessage types, since we don't have
389
0
  // any use for them.
390
0
}
391
392
0
TEST_F(SdpTest, parseRtcpFbCcmFoo) {
393
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm foo\r\n");
394
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
395
0
            SDP_RTCP_FB_CCM_UNKNOWN);
396
0
}
397
398
0
TEST_F(SdpTest, parseRtcpFbCcmFooBarBaz) {
399
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 ccm foo bar baz\r\n");
400
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1),
401
0
            SDP_RTCP_FB_CCM_UNKNOWN);
402
0
}
403
404
0
TEST_F(SdpTest, parseRtcpFbFoo) {
405
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 foo\r\n");
406
0
}
407
408
0
TEST_F(SdpTest, parseRtcpFbFooBar) {
409
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 foo bar\r\n");
410
0
}
411
412
0
TEST_F(SdpTest, parseRtcpFbFooBarBaz) {
413
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:120 foo bar baz\r\n");
414
0
}
415
416
static const std::string kVideoSdpWithUnknonwBrokenFtmp =
417
  "v=0\r\n"
418
  "o=- 4294967296 2 IN IP4 127.0.0.1\r\n"
419
  "s=SIP Call\r\n"
420
  "c=IN IP4 198.51.100.7\r\n"
421
  "t=0 0\r\n"
422
  "m=video 56436 RTP/SAVPF 120\r\n"
423
  "a=rtpmap:120 VP8/90000\r\n"
424
  "a=fmtp:122 unknown=10\n"
425
  "a=rtpmap:122 red/90000\r\n";
426
427
0
TEST_F(SdpTest, parseUnknownBrokenFtmp) {
428
0
  ParseSdp(kVideoSdpWithUnknonwBrokenFtmp);
429
0
}
430
431
0
TEST_F(SdpTest, parseRtcpFbKitchenSink) {
432
0
  ParseSdp(kVideoSdp +
433
0
    "a=rtcp-fb:120 ack rpsi\r\n"
434
0
    "a=rtcp-fb:120 ack app\r\n"
435
0
    "a=rtcp-fb:120 ack app foo\r\n"
436
0
    "a=rtcp-fb:120 ack foo bar\r\n"
437
0
    "a=rtcp-fb:120 ack foo bar baz\r\n"
438
0
    "a=rtcp-fb:120 nack\r\n"
439
0
    "a=rtcp-fb:120 nack pli\r\n"
440
0
    "a=rtcp-fb:120 nack sli\r\n"
441
0
    "a=rtcp-fb:120 nack rpsi\r\n"
442
0
    "a=rtcp-fb:120 nack app\r\n"
443
0
    "a=rtcp-fb:120 nack app foo\r\n"
444
0
    "a=rtcp-fb:120 nack app foo bar\r\n"
445
0
    "a=rtcp-fb:120 nack foo bar baz\r\n"
446
0
    "a=rtcp-fb:120 trr-int 0\r\n"
447
0
    "a=rtcp-fb:120 trr-int 123\r\n"
448
0
    "a=rtcp-fb:120 goog-remb\r\n"
449
0
    "a=rtcp-fb:120 ccm fir\r\n"
450
0
    "a=rtcp-fb:120 ccm tmmbr\r\n"
451
0
    "a=rtcp-fb:120 ccm tmmbr smaxpr=456\r\n"
452
0
    "a=rtcp-fb:120 ccm tstr\r\n"
453
0
    "a=rtcp-fb:120 ccm vbcm 123 456 789\r\n"
454
0
    "a=rtcp-fb:120 ccm foo\r\n"
455
0
    "a=rtcp-fb:120 ccm foo bar baz\r\n"
456
0
    "a=rtcp-fb:120 foo\r\n"
457
0
    "a=rtcp-fb:120 foo bar\r\n"
458
0
    "a=rtcp-fb:120 foo bar baz\r\n");
459
0
460
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_ACK_RPSI);
461
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 2), SDP_RTCP_FB_ACK_APP);
462
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 3), SDP_RTCP_FB_ACK_APP);
463
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 4),
464
0
            SDP_RTCP_FB_ACK_UNKNOWN);
465
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 5),
466
0
            SDP_RTCP_FB_ACK_UNKNOWN);
467
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, 120, 6),
468
0
            SDP_RTCP_FB_ACK_NOT_FOUND);
469
0
470
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 1),
471
0
            SDP_RTCP_FB_NACK_BASIC);
472
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 2),
473
0
            SDP_RTCP_FB_NACK_PLI);
474
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 3),
475
0
            SDP_RTCP_FB_NACK_SLI);
476
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 4),
477
0
            SDP_RTCP_FB_NACK_RPSI);
478
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 5),
479
0
            SDP_RTCP_FB_NACK_APP);
480
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 6),
481
0
            SDP_RTCP_FB_NACK_APP);
482
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 7),
483
0
            SDP_RTCP_FB_NACK_APP);
484
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 8),
485
0
            SDP_RTCP_FB_NACK_UNKNOWN);
486
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_nack(sdp_ptr_, 1, 120, 9),
487
0
            SDP_RTCP_FB_NACK_NOT_FOUND);
488
0
489
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 1), 0U);
490
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 2), 123U);
491
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_trr_int(sdp_ptr_, 1, 120, 3), 0xFFFFFFFF);
492
0
493
0
  ASSERT_EQ((bool)sdp_attr_get_rtcp_fb_remb_enabled(sdp_ptr_, 1, 120), true);
494
0
  ASSERT_EQ((bool)sdp_attr_get_rtcp_fb_remb_enabled(sdp_ptr_, 2, 120), false);
495
0
496
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 1), SDP_RTCP_FB_CCM_FIR);
497
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 2),
498
0
            SDP_RTCP_FB_CCM_TMMBR);
499
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 3),
500
0
            SDP_RTCP_FB_CCM_TMMBR);
501
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 4),
502
0
            SDP_RTCP_FB_CCM_TSTR);
503
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 5),
504
0
            SDP_RTCP_FB_CCM_VBCM);
505
0
  // We don't currently parse out VBCM submessage types, since we don't have
506
0
  // any use for them.
507
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 6),
508
0
            SDP_RTCP_FB_CCM_UNKNOWN);
509
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 7),
510
0
            SDP_RTCP_FB_CCM_UNKNOWN);
511
0
  ASSERT_EQ(sdp_attr_get_rtcp_fb_ccm(sdp_ptr_, 1, 120, 8),
512
0
            SDP_RTCP_FB_CCM_NOT_FOUND);
513
0
}
514
515
0
TEST_F(SdpTest, addRtcpFbAckRpsi) {
516
0
  InitLocalSdp();
517
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
518
0
  AddNewRtcpFbAck(level, SDP_RTCP_FB_ACK_RPSI, 120);
519
0
  std::string body = SerializeSdp();
520
0
  ASSERT_NE(body.find("a=rtcp-fb:120 ack rpsi\r\n"), std::string::npos);
521
0
}
522
523
0
TEST_F(SdpTest, addRtcpFbAckRpsiAllPt) {
524
0
  InitLocalSdp();
525
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
526
0
  AddNewRtcpFbAck(level, SDP_RTCP_FB_ACK_RPSI);
527
0
  std::string body = SerializeSdp();
528
0
  ASSERT_NE(body.find("a=rtcp-fb:* ack rpsi\r\n"), std::string::npos);
529
0
}
530
531
0
TEST_F(SdpTest, addRtcpFbAckApp) {
532
0
  InitLocalSdp();
533
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
534
0
  AddNewRtcpFbAck(level, SDP_RTCP_FB_ACK_APP, 120);
535
0
  std::string body = SerializeSdp();
536
0
  ASSERT_NE(body.find("a=rtcp-fb:120 ack app\r\n"), std::string::npos);
537
0
}
538
539
0
TEST_F(SdpTest, addRtcpFbAckAppAllPt) {
540
0
  InitLocalSdp();
541
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
542
0
  AddNewRtcpFbAck(level, SDP_RTCP_FB_ACK_APP);
543
0
  std::string body = SerializeSdp();
544
0
  ASSERT_NE(body.find("a=rtcp-fb:* ack app\r\n"), std::string::npos);
545
0
}
546
547
0
TEST_F(SdpTest, addRtcpFbNack) {
548
0
  InitLocalSdp();
549
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
550
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_BASIC, 120);
551
0
  std::string body = SerializeSdp();
552
0
  ASSERT_NE(body.find("a=rtcp-fb:120 nack\r\n"), std::string::npos);
553
0
}
554
555
0
TEST_F(SdpTest, addRtcpFbNackAllPt) {
556
0
  InitLocalSdp();
557
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
558
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_BASIC);
559
0
  std::string body = SerializeSdp();
560
0
  ASSERT_NE(body.find("a=rtcp-fb:* nack\r\n"), std::string::npos);
561
0
}
562
563
0
TEST_F(SdpTest, addRtcpFbNackSli) {
564
0
  InitLocalSdp();
565
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
566
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_SLI, 120);
567
0
  std::string body = SerializeSdp();
568
0
  ASSERT_NE(body.find("a=rtcp-fb:120 nack sli\r\n"), std::string::npos);
569
0
}
570
571
0
TEST_F(SdpTest, addRtcpFbNackSliAllPt) {
572
0
  InitLocalSdp();
573
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
574
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_SLI);
575
0
  std::string body = SerializeSdp();
576
0
  ASSERT_NE(body.find("a=rtcp-fb:* nack sli\r\n"), std::string::npos);
577
0
}
578
579
0
TEST_F(SdpTest, addRtcpFbNackPli) {
580
0
  InitLocalSdp();
581
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
582
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_PLI, 120);
583
0
  std::string body = SerializeSdp();
584
0
  ASSERT_NE(body.find("a=rtcp-fb:120 nack pli\r\n"), std::string::npos);
585
0
}
586
587
0
TEST_F(SdpTest, addRtcpFbNackPliAllPt) {
588
0
  InitLocalSdp();
589
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
590
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_PLI);
591
0
  std::string body = SerializeSdp();
592
0
  ASSERT_NE(body.find("a=rtcp-fb:* nack pli\r\n"), std::string::npos);
593
0
}
594
595
0
TEST_F(SdpTest, addRtcpFbNackRpsi) {
596
0
  InitLocalSdp();
597
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
598
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_RPSI, 120);
599
0
  std::string body = SerializeSdp();
600
0
  ASSERT_NE(body.find("a=rtcp-fb:120 nack rpsi\r\n"), std::string::npos);
601
0
}
602
603
0
TEST_F(SdpTest, addRtcpFbNackRpsiAllPt) {
604
0
  InitLocalSdp();
605
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
606
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_RPSI);
607
0
  std::string body = SerializeSdp();
608
0
  ASSERT_NE(body.find("a=rtcp-fb:* nack rpsi\r\n"), std::string::npos);
609
0
}
610
611
0
TEST_F(SdpTest, addRtcpFbNackApp) {
612
0
  InitLocalSdp();
613
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
614
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_APP, 120);
615
0
  std::string body = SerializeSdp();
616
0
  ASSERT_NE(body.find("a=rtcp-fb:120 nack app\r\n"), std::string::npos);
617
0
}
618
619
0
TEST_F(SdpTest, addRtcpFbNackAppAllPt) {
620
0
  InitLocalSdp();
621
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
622
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_APP);
623
0
  std::string body = SerializeSdp();
624
0
  ASSERT_NE(body.find("a=rtcp-fb:* nack app\r\n"), std::string::npos);
625
0
}
626
627
0
TEST_F(SdpTest, addRtcpFbNackRai) {
628
0
  InitLocalSdp();
629
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
630
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_RAI, 120);
631
0
  std::string body = SerializeSdp();
632
0
  ASSERT_NE(body.find("a=rtcp-fb:120 nack rai\r\n"), std::string::npos);
633
0
}
634
635
0
TEST_F(SdpTest, addRtcpFbNackRaiAllPt) {
636
0
  InitLocalSdp();
637
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
638
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_RAI);
639
0
  std::string body = SerializeSdp();
640
0
  ASSERT_NE(body.find("a=rtcp-fb:* nack rai\r\n"), std::string::npos);
641
0
}
642
643
0
TEST_F(SdpTest, addRtcpFbNackTllei) {
644
0
  InitLocalSdp();
645
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
646
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_TLLEI, 120);
647
0
  std::string body = SerializeSdp();
648
0
  ASSERT_NE(body.find("a=rtcp-fb:120 nack tllei\r\n"), std::string::npos);
649
0
}
650
651
0
TEST_F(SdpTest, addRtcpFbNackTlleiAllPt) {
652
0
  InitLocalSdp();
653
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
654
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_TLLEI);
655
0
  std::string body = SerializeSdp();
656
0
  ASSERT_NE(body.find("a=rtcp-fb:* nack tllei\r\n"), std::string::npos);
657
0
}
658
659
0
TEST_F(SdpTest, addRtcpFbNackPslei) {
660
0
  InitLocalSdp();
661
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
662
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_PSLEI, 120);
663
0
  std::string body = SerializeSdp();
664
0
  ASSERT_NE(body.find("a=rtcp-fb:120 nack pslei\r\n"), std::string::npos);
665
0
}
666
667
0
TEST_F(SdpTest, addRtcpFbNackPsleiAllPt) {
668
0
  InitLocalSdp();
669
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
670
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_PSLEI);
671
0
  std::string body = SerializeSdp();
672
0
  ASSERT_NE(body.find("a=rtcp-fb:* nack pslei\r\n"), std::string::npos);
673
0
}
674
675
0
TEST_F(SdpTest, addRtcpFbNackEcn) {
676
0
  InitLocalSdp();
677
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
678
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_ECN, 120);
679
0
  std::string body = SerializeSdp();
680
0
  ASSERT_NE(body.find("a=rtcp-fb:120 nack ecn\r\n"), std::string::npos);
681
0
}
682
683
0
TEST_F(SdpTest, addRtcpFbNackEcnAllPt) {
684
0
  InitLocalSdp();
685
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
686
0
  AddNewRtcpFbNack(level, SDP_RTCP_FB_NACK_ECN);
687
0
  std::string body = SerializeSdp();
688
0
  ASSERT_NE(body.find("a=rtcp-fb:* nack ecn\r\n"), std::string::npos);
689
0
}
690
691
0
TEST_F(SdpTest, addRtcpFbRemb) {
692
0
  InitLocalSdp();
693
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
694
0
  AddNewRtcpFbRemb(level, 120);
695
0
  std::string body = SerializeSdp();
696
0
  ASSERT_NE(body.find("a=rtcp-fb:120 goog-remb\r\n"), std::string::npos);
697
0
}
698
699
0
TEST_F(SdpTest, addRtcpFbRembAllPt) {
700
0
  InitLocalSdp();
701
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
702
0
  AddNewRtcpFbRemb(level);
703
0
  std::string body = SerializeSdp();
704
0
  ASSERT_NE(body.find("a=rtcp-fb:* goog-remb\r\n"), std::string::npos);
705
0
}
706
707
0
TEST_F(SdpTest, addRtcpFbTrrInt) {
708
0
  InitLocalSdp();
709
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
710
0
  AddNewRtcpFbTrrInt(level, 12345, 120);
711
0
  std::string body = SerializeSdp();
712
0
  ASSERT_NE(body.find("a=rtcp-fb:120 trr-int 12345\r\n"), std::string::npos);
713
0
}
714
715
0
TEST_F(SdpTest, addRtcpFbNackTrrIntAllPt) {
716
0
  InitLocalSdp();
717
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
718
0
  AddNewRtcpFbTrrInt(level, 0);
719
0
  std::string body = SerializeSdp();
720
0
  ASSERT_NE(body.find("a=rtcp-fb:* trr-int 0\r\n"), std::string::npos);
721
0
}
722
723
0
TEST_F(SdpTest, addRtcpFbCcmFir) {
724
0
  InitLocalSdp();
725
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
726
0
  AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_FIR, 120);
727
0
  std::string body = SerializeSdp();
728
0
  ASSERT_NE(body.find("a=rtcp-fb:120 ccm fir\r\n"), std::string::npos);
729
0
}
730
731
0
TEST_F(SdpTest, addRtcpFbCcmFirAllPt) {
732
0
  InitLocalSdp();
733
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
734
0
  AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_FIR);
735
0
  std::string body = SerializeSdp();
736
0
  ASSERT_NE(body.find("a=rtcp-fb:* ccm fir\r\n"), std::string::npos);
737
0
}
738
739
0
TEST_F(SdpTest, addRtcpFbCcmTmmbr) {
740
0
  InitLocalSdp();
741
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
742
0
  AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_TMMBR, 120);
743
0
  std::string body = SerializeSdp();
744
0
  ASSERT_NE(body.find("a=rtcp-fb:120 ccm tmmbr\r\n"), std::string::npos);
745
0
}
746
747
0
TEST_F(SdpTest, addRtcpFbCcmTmmbrAllPt) {
748
0
  InitLocalSdp();
749
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
750
0
  AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_TMMBR);
751
0
  std::string body = SerializeSdp();
752
0
  ASSERT_NE(body.find("a=rtcp-fb:* ccm tmmbr\r\n"), std::string::npos);
753
0
}
754
755
0
TEST_F(SdpTest, addRtcpFbCcmTstr) {
756
0
  InitLocalSdp();
757
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
758
0
  AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_TSTR, 120);
759
0
  std::string body = SerializeSdp();
760
0
  ASSERT_NE(body.find("a=rtcp-fb:120 ccm tstr\r\n"), std::string::npos);
761
0
}
762
763
0
TEST_F(SdpTest, addRtcpFbCcmTstrAllPt) {
764
0
  InitLocalSdp();
765
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
766
0
  AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_TSTR);
767
0
  std::string body = SerializeSdp();
768
0
  ASSERT_NE(body.find("a=rtcp-fb:* ccm tstr\r\n"), std::string::npos);
769
0
}
770
771
0
TEST_F(SdpTest, addRtcpFbCcmVbcm) {
772
0
  InitLocalSdp();
773
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
774
0
  AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_VBCM, 120);
775
0
  std::string body = SerializeSdp();
776
0
  ASSERT_NE(body.find("a=rtcp-fb:120 ccm vbcm\r\n"), std::string::npos);
777
0
}
778
779
0
TEST_F(SdpTest, addRtcpFbCcmVbcmAllPt) {
780
0
  InitLocalSdp();
781
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
782
0
  AddNewRtcpFbCcm(level, SDP_RTCP_FB_CCM_VBCM);
783
0
  std::string body = SerializeSdp();
784
0
  ASSERT_NE(body.find("a=rtcp-fb:* ccm vbcm\r\n"), std::string::npos);
785
0
}
786
787
0
TEST_F(SdpTest, parseRtcpFbAllPayloads) {
788
0
  ParseSdp(kVideoSdp + "a=rtcp-fb:* ack rpsi\r\n");
789
0
  for (int i = 0; i < 128; i++) {
790
0
    ASSERT_EQ(sdp_attr_get_rtcp_fb_ack(sdp_ptr_, 1, i, 1),
791
0
              SDP_RTCP_FB_ACK_RPSI);
792
0
  }
793
0
}
794
0
TEST_F(SdpTest, addExtMap) {
795
0
  InitLocalSdp();
796
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
797
0
  AddNewExtMap(level, SDP_EXTMAP_AUDIO_LEVEL);
798
0
  std::string body = SerializeSdp();
799
0
  ASSERT_NE(body.find("a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"), std::string::npos);
800
0
}
801
802
0
TEST_F(SdpTest, parseExtMap) {
803
0
  ParseSdp(kVideoSdp +
804
0
    "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n");
805
0
  ASSERT_STREQ(sdp_attr_get_extmap_uri(sdp_ptr_, 1, 1),
806
0
            SDP_EXTMAP_AUDIO_LEVEL);
807
0
  ASSERT_EQ(sdp_attr_get_extmap_id(sdp_ptr_, 1, 1),
808
0
            1);
809
0
810
0
}
811
812
0
TEST_F(SdpTest, parseFmtpBitrate) {
813
0
  ParseSdp(kVideoSdp + "a=fmtp:120 bitrate=400\r\n");
814
0
  ASSERT_EQ(400, sdp_attr_get_fmtp_bitrate_type(sdp_ptr_, 1, 0, 1));
815
0
}
816
817
0
TEST_F(SdpTest, parseFmtpBitrateWith0) {
818
0
  ParseSdp(kVideoSdp + "a=fmtp:120 bitrate=0\r\n");
819
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_bitrate_type(sdp_ptr_, 1, 0, 1));
820
0
}
821
822
0
TEST_F(SdpTest, parseFmtpBitrateWith32001) {
823
0
  ParseSdp(kVideoSdp + "a=fmtp:120 bitrate=32001\r\n");
824
0
  ASSERT_EQ(32001, sdp_attr_get_fmtp_bitrate_type(sdp_ptr_, 1, 0, 1));
825
0
}
826
827
0
TEST_F(SdpTest, parseFmtpBitrateWith4294967296) {
828
0
  ParseSdp(kVideoSdp + "a=fmtp:120 bitrate=4294967296\r\n");
829
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_bitrate_type(sdp_ptr_, 1, 0, 1));
830
0
}
831
832
0
TEST_F(SdpTest, parseFmtpMode) {
833
0
  ParseSdp(kVideoSdp + "a=fmtp:120 mode=200\r\n");
834
0
  ASSERT_EQ(200U, sdp_attr_get_fmtp_mode_for_payload_type(sdp_ptr_, 1, 0, 120));
835
0
}
836
837
0
TEST_F(SdpTest, parseFmtpModeWith4294967295) {
838
0
  ParseSdp(kVideoSdp + "a=fmtp:120 mode=4294967295\r\n");
839
0
  ASSERT_EQ(4294967295, sdp_attr_get_fmtp_mode_for_payload_type(sdp_ptr_, 1, 0, 120));
840
0
}
841
842
0
TEST_F(SdpTest, parseFmtpModeWith4294967296) {
843
0
  ParseSdp(kVideoSdp + "a=fmtp:120 mode=4294967296\r\n");
844
0
  // returns 0 if not found
845
0
  ASSERT_EQ(0U, sdp_attr_get_fmtp_mode_for_payload_type(sdp_ptr_, 1, 0, 120));
846
0
}
847
848
0
TEST_F(SdpTest, parseFmtpQcif) {
849
0
  ParseSdp(kVideoSdp + "a=fmtp:120 qcif=20\r\n");
850
0
  ASSERT_EQ(20, sdp_attr_get_fmtp_qcif(sdp_ptr_, 1, 0, 1));
851
0
}
852
853
0
TEST_F(SdpTest, parseFmtpQcifWith0) {
854
0
  ParseSdp(kVideoSdp + "a=fmtp:120 qcif=0\r\n");
855
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_qcif(sdp_ptr_, 1, 0, 1));
856
0
}
857
858
0
TEST_F(SdpTest, parseFmtpQcifWith33) {
859
0
  ParseSdp(kVideoSdp + "a=fmtp:120 qcif=33\r\n");
860
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_qcif(sdp_ptr_, 1, 0, 1));
861
0
}
862
863
0
TEST_F(SdpTest, parseFmtpCif) {
864
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cif=11\r\n");
865
0
  ASSERT_EQ(11, sdp_attr_get_fmtp_cif(sdp_ptr_, 1, 0, 1));
866
0
}
867
868
0
TEST_F(SdpTest, parseFmtpCifWith0) {
869
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cif=0\r\n");
870
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_cif(sdp_ptr_, 1, 0, 1));
871
0
}
872
873
0
TEST_F(SdpTest, parseFmtpCifWith33) {
874
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cif=33\r\n");
875
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_cif(sdp_ptr_, 1, 0, 1));
876
0
}
877
878
0
TEST_F(SdpTest, parseFmtpMaxbr) {
879
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxbr=21\r\n");
880
0
  ASSERT_EQ(21, sdp_attr_get_fmtp_maxbr(sdp_ptr_, 1, 0, 1));
881
0
}
882
883
0
TEST_F(SdpTest, parseFmtpMaxbrWith0) {
884
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxbr=0\r\n");
885
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_maxbr(sdp_ptr_, 1, 0, 1));
886
0
}
887
888
0
TEST_F(SdpTest, parseFmtpMaxbrWith65536) {
889
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxbr=65536\r\n");
890
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_maxbr(sdp_ptr_, 1, 0, 1));
891
0
}
892
893
0
TEST_F(SdpTest, parseFmtpSqcif) {
894
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sqcif=6\r\n");
895
0
  ASSERT_EQ(6, sdp_attr_get_fmtp_sqcif(sdp_ptr_, 1, 0, 1));
896
0
}
897
898
0
TEST_F(SdpTest, parseFmtpSqcifWith0) {
899
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sqcif=0\r\n");
900
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_sqcif(sdp_ptr_, 1, 0, 1));
901
0
}
902
903
0
TEST_F(SdpTest, parseFmtpSqcifWith33) {
904
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sqcif=33\r\n");
905
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_sqcif(sdp_ptr_, 1, 0, 1));
906
0
}
907
908
0
TEST_F(SdpTest, parseFmtpCif4) {
909
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cif4=11\r\n");
910
0
  ASSERT_EQ(11, sdp_attr_get_fmtp_cif4(sdp_ptr_, 1, 0, 1));
911
0
}
912
913
0
TEST_F(SdpTest, parseFmtpCif4With0) {
914
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cif4=0\r\n");
915
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_cif4(sdp_ptr_, 1, 0, 1));
916
0
}
917
918
0
TEST_F(SdpTest, parseFmtpCif4With33) {
919
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cif4=33\r\n");
920
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_cif4(sdp_ptr_, 1, 0, 1));
921
0
}
922
923
0
TEST_F(SdpTest, parseFmtpCif16) {
924
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cif16=11\r\n");
925
0
  ASSERT_EQ(11, sdp_attr_get_fmtp_cif16(sdp_ptr_, 1, 0, 1));
926
0
}
927
928
0
TEST_F(SdpTest, parseFmtpCif16With0) {
929
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cif16=0\r\n");
930
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_cif16(sdp_ptr_, 1, 0, 1));
931
0
}
932
933
0
TEST_F(SdpTest, parseFmtpCif16With33) {
934
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cif16=33\r\n");
935
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_cif16(sdp_ptr_, 1, 0, 1));
936
0
}
937
938
0
TEST_F(SdpTest, parseFmtpBpp) {
939
0
  ParseSdp(kVideoSdp + "a=fmtp:120 bpp=7\r\n");
940
0
  ASSERT_EQ(7, sdp_attr_get_fmtp_bpp(sdp_ptr_, 1, 0, 1));
941
0
}
942
943
0
TEST_F(SdpTest, parseFmtpBppWith0) {
944
0
  ParseSdp(kVideoSdp + "a=fmtp:120 bpp=0\r\n");
945
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_bpp(sdp_ptr_, 1, 0, 1));
946
0
}
947
948
0
TEST_F(SdpTest, parseFmtpBppWith65536) {
949
0
  ParseSdp(kVideoSdp + "a=fmtp:120 bpp=65536\r\n");
950
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_bpp(sdp_ptr_, 1, 0, 1));
951
0
}
952
953
0
TEST_F(SdpTest, parseFmtpHrd) {
954
0
  ParseSdp(kVideoSdp + "a=fmtp:120 hrd=800\r\n");
955
0
  ASSERT_EQ(800, sdp_attr_get_fmtp_hrd(sdp_ptr_, 1, 0, 1));
956
0
}
957
958
0
TEST_F(SdpTest, parseFmtpHrdWith0) {
959
0
  ParseSdp(kVideoSdp + "a=fmtp:120 hrd=0\r\n");
960
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_hrd(sdp_ptr_, 1, 0, 1));
961
0
}
962
963
0
TEST_F(SdpTest, parseFmtpHrdWith65536) {
964
0
  ParseSdp(kVideoSdp + "a=fmtp:120 hrd=65536\r\n");
965
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_hrd(sdp_ptr_, 1, 0, 1));
966
0
}
967
968
0
TEST_F(SdpTest, parseFmtpProfile) {
969
0
  ParseSdp(kVideoSdp + "a=fmtp:120 profile=4\r\n");
970
0
  ASSERT_EQ(4, sdp_attr_get_fmtp_profile(sdp_ptr_, 1, 0, 1));
971
0
}
972
973
0
TEST_F(SdpTest, parseFmtpProfileWith11) {
974
0
  ParseSdp(kVideoSdp + "a=fmtp:120 profile=11\r\n");
975
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_profile(sdp_ptr_, 1, 0, 1));
976
0
}
977
978
0
TEST_F(SdpTest, parseFmtpLevel) {
979
0
  ParseSdp(kVideoSdp + "a=fmtp:120 level=56\r\n");
980
0
  ASSERT_EQ(56, sdp_attr_get_fmtp_level(sdp_ptr_, 1, 0, 1));
981
0
}
982
983
0
TEST_F(SdpTest, parseFmtpLevelWith101) {
984
0
  ParseSdp(kVideoSdp + "a=fmtp:120 level=101\r\n");
985
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_level(sdp_ptr_, 1, 0, 1));
986
0
}
987
988
0
TEST_F(SdpTest, parseFmtpPacketizationMode) {
989
0
  ParseSdp(kVideoSdp + "a=fmtp:120 packetization-mode=1\r\n");
990
0
  uint16_t packetizationMode;
991
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_pack_mode(sdp_ptr_, 1, 0, 1, &packetizationMode));
992
0
  ASSERT_EQ(1, packetizationMode);
993
0
}
994
995
0
TEST_F(SdpTest, parseFmtpPacketizationModeWith3) {
996
0
  ParseSdp(kVideoSdp + "a=fmtp:120 packetization-mode=3\r\n");
997
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_pack_mode(sdp_ptr_, 1, 0, 1, nullptr));
998
0
}
999
1000
0
TEST_F(SdpTest, parseFmtpInterleavingDepth) {
1001
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-interleaving-depth=566\r\n");
1002
0
  uint16_t interleavingDepth;
1003
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_interleaving_depth(sdp_ptr_, 1, 0, 1, &interleavingDepth));
1004
0
  ASSERT_EQ(566, interleavingDepth);
1005
0
}
1006
1007
0
TEST_F(SdpTest, parseFmtpInterleavingDepthWith0) {
1008
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-interleaving-depth=0\r\n");
1009
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_interleaving_depth(sdp_ptr_, 1, 0, 1, nullptr));
1010
0
}
1011
1012
0
TEST_F(SdpTest, parseFmtpInterleavingDepthWith65536) {
1013
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-interleaving-depth=65536\r\n");
1014
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_interleaving_depth(sdp_ptr_, 1, 0, 1, nullptr));
1015
0
}
1016
1017
0
TEST_F(SdpTest, parseFmtpDeintBuf) {
1018
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-deint-buf-req=4294967295\r\n");
1019
0
  uint32_t deintBuf;
1020
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_deint_buf_req(sdp_ptr_, 1, 0, 1, &deintBuf));
1021
0
  ASSERT_EQ(4294967295, deintBuf);
1022
0
}
1023
1024
0
TEST_F(SdpTest, parseFmtpDeintBufWith0) {
1025
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-deint-buf-req=0\r\n");
1026
0
  uint32_t deintBuf;
1027
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_deint_buf_req(sdp_ptr_, 1, 0, 1, &deintBuf));
1028
0
  ASSERT_EQ(0U, deintBuf);
1029
0
}
1030
1031
0
TEST_F(SdpTest, parseFmtpDeintBufWith4294967296) {
1032
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-deint-buf-req=4294967296\r\n");
1033
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_deint_buf_req(sdp_ptr_, 1, 0, 1, nullptr));
1034
0
}
1035
1036
0
TEST_F(SdpTest, parseFmtpMaxDonDiff) {
1037
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-max-don-diff=5678\r\n");
1038
0
  uint32_t maxDonDiff;
1039
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_max_don_diff(sdp_ptr_, 1, 0, 1, &maxDonDiff));
1040
0
  ASSERT_EQ(5678U, maxDonDiff);
1041
0
}
1042
1043
0
TEST_F(SdpTest, parseFmtpMaxDonDiffWith0) {
1044
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-max-don-diff=0\r\n");
1045
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_don_diff(sdp_ptr_, 1, 0, 1, nullptr));
1046
0
}
1047
1048
0
TEST_F(SdpTest, parseFmtpMaxDonDiffWith4294967296) {
1049
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-max-don-diff=4294967296\r\n");
1050
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_don_diff(sdp_ptr_, 1, 0, 1, nullptr));
1051
0
}
1052
1053
0
TEST_F(SdpTest, parseFmtpInitBufTime) {
1054
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-init-buf-time=4294967295\r\n");
1055
0
  uint32_t initBufTime;
1056
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_init_buf_time(sdp_ptr_, 1, 0, 1, &initBufTime));
1057
0
  ASSERT_EQ(4294967295, initBufTime);
1058
0
}
1059
1060
0
TEST_F(SdpTest, parseFmtpInitBufTimeWith0) {
1061
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-init-buf-time=0\r\n");
1062
0
  uint32_t initBufTime;
1063
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_init_buf_time(sdp_ptr_, 1, 0, 1, &initBufTime));
1064
0
  ASSERT_EQ(0U, initBufTime);
1065
0
}
1066
1067
0
TEST_F(SdpTest, parseFmtpInitBufTimeWith4294967296) {
1068
0
  ParseSdp(kVideoSdp + "a=fmtp:120 sprop-init-buf-time=4294967296\r\n");
1069
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_init_buf_time(sdp_ptr_, 1, 0, 1, nullptr));
1070
0
}
1071
1072
0
TEST_F(SdpTest, parseFmtpMaxMbps) {
1073
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-mbps=46789\r\n");
1074
0
  uint32_t maxMpbs;
1075
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_max_mbps(sdp_ptr_, 1, 0, 1, &maxMpbs));
1076
0
  ASSERT_EQ(46789U, maxMpbs);
1077
0
}
1078
1079
0
TEST_F(SdpTest, parseFmtpMaxMbpsWith0) {
1080
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-mbps=0\r\n");
1081
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_mbps(sdp_ptr_, 1, 0, 1, nullptr));
1082
0
}
1083
1084
0
TEST_F(SdpTest, parseFmtpMaxMbpsWith4294967296) {
1085
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-mbps=4294967296\r\n");
1086
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_mbps(sdp_ptr_, 1, 0, 1, nullptr));
1087
0
}
1088
1089
0
TEST_F(SdpTest, parseFmtpMaxCpb) {
1090
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-cpb=47891\r\n");
1091
0
  uint32_t maxCpb;
1092
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_max_cpb(sdp_ptr_, 1, 0, 1, &maxCpb));
1093
0
  ASSERT_EQ(47891U, maxCpb);
1094
0
}
1095
1096
0
TEST_F(SdpTest, parseFmtpMaxCpbWith0) {
1097
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-cpb=0\r\n");
1098
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_cpb(sdp_ptr_, 1, 0, 1, nullptr));
1099
0
}
1100
1101
0
TEST_F(SdpTest, parseFmtpMaxCpbWith4294967296) {
1102
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-cpb=4294967296\r\n");
1103
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_cpb(sdp_ptr_, 1, 0, 1, nullptr));
1104
0
}
1105
1106
0
TEST_F(SdpTest, parseFmtpMaxDpb) {
1107
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-dpb=47892\r\n");
1108
0
  uint32_t maxDpb;
1109
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_max_dpb(sdp_ptr_, 1, 0, 1, &maxDpb));
1110
0
  ASSERT_EQ(47892U, maxDpb);
1111
0
}
1112
1113
0
TEST_F(SdpTest, parseFmtpMaxDpbWith0) {
1114
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-dpb=0\r\n");
1115
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_dpb(sdp_ptr_, 1, 0, 1, nullptr));
1116
0
}
1117
1118
0
TEST_F(SdpTest, parseFmtpMaxDpbWith4294967296) {
1119
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-dpb=4294967296\r\n");
1120
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_dpb(sdp_ptr_, 1, 0, 1, nullptr));
1121
0
}
1122
1123
0
TEST_F(SdpTest, parseFmtpMaxBr) {
1124
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-br=47893\r\n");
1125
0
  uint32_t maxBr;
1126
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_max_br(sdp_ptr_, 1, 0, 1, &maxBr));
1127
0
  ASSERT_EQ(47893U, maxBr);
1128
0
}
1129
1130
0
TEST_F(SdpTest, parseFmtpMaxBrWith0) {
1131
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-br=0\r\n");
1132
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_br(sdp_ptr_, 1, 0, 1, nullptr));
1133
0
}
1134
1135
0
TEST_F(SdpTest, parseFmtpMaxBrWith4294967296) {
1136
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-br=4294967296\r\n");
1137
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_br(sdp_ptr_, 1, 0, 1, nullptr));
1138
0
}
1139
1140
0
TEST_F(SdpTest, parseFmtpRedundantPicCap) {
1141
0
  ParseSdp(kVideoSdp + "a=fmtp:120 redundant-pic-cap=1\r\n");
1142
0
  ASSERT_EQ(1, sdp_attr_fmtp_is_redundant_pic_cap(sdp_ptr_, 1, 0, 1));
1143
0
}
1144
1145
0
TEST_F(SdpTest, parseFmtpRedundantPicCapWith0) {
1146
0
  ParseSdp(kVideoSdp + "a=fmtp:120 redundant-pic-cap=0\r\n");
1147
0
  ASSERT_EQ(0, sdp_attr_fmtp_is_redundant_pic_cap(sdp_ptr_, 1, 0, 1));
1148
0
}
1149
1150
0
TEST_F(SdpTest, parseFmtpRedundantPicCapWith2) {
1151
0
  ParseSdp(kVideoSdp + "a=fmtp:120 redundant-pic-cap=2\r\n");
1152
0
  ASSERT_EQ(0, sdp_attr_fmtp_is_redundant_pic_cap(sdp_ptr_, 1, 0, 1));
1153
0
}
1154
1155
0
TEST_F(SdpTest, parseFmtpDeintBufCap) {
1156
0
  ParseSdp(kVideoSdp + "a=fmtp:120 deint-buf-cap=4294967295\r\n");
1157
0
  uint32_t deintBufCap;
1158
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_deint_buf_cap(sdp_ptr_, 1, 0, 1, &deintBufCap));
1159
0
  ASSERT_EQ(4294967295, deintBufCap);
1160
0
}
1161
1162
0
TEST_F(SdpTest, parseFmtpDeintBufCapWith0) {
1163
0
  ParseSdp(kVideoSdp + "a=fmtp:120 deint-buf-cap=0\r\n");
1164
0
  uint32_t deintBufCap;
1165
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_deint_buf_cap(sdp_ptr_, 1, 0, 1, &deintBufCap));
1166
0
  ASSERT_EQ(0U, deintBufCap);
1167
0
}
1168
1169
0
TEST_F(SdpTest, parseFmtpDeintBufCapWith4294967296) {
1170
0
  ParseSdp(kVideoSdp + "a=fmtp:120 deint-buf-cap=4294967296\r\n");
1171
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_deint_buf_cap(sdp_ptr_, 1, 0, 1, nullptr));
1172
0
}
1173
1174
0
TEST_F(SdpTest, parseFmtpMaxRcmdNaluSize) {
1175
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-rcmd-nalu-size=4294967295\r\n");
1176
0
  uint32_t maxRcmdNaluSize;
1177
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_max_rcmd_nalu_size(sdp_ptr_, 1, 0, 1, &maxRcmdNaluSize));
1178
0
  ASSERT_EQ(4294967295, maxRcmdNaluSize);
1179
0
}
1180
1181
0
TEST_F(SdpTest, parseFmtpMaxRcmdNaluSizeWith0) {
1182
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-rcmd-nalu-size=0\r\n");
1183
0
  uint32_t maxRcmdNaluSize;
1184
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_max_rcmd_nalu_size(sdp_ptr_, 1, 0, 1, &maxRcmdNaluSize));
1185
0
  ASSERT_EQ(0U, maxRcmdNaluSize);
1186
0
}
1187
1188
0
TEST_F(SdpTest, parseFmtpMaxRcmdNaluSizeWith4294967296) {
1189
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-rcmd-nalu-size=4294967296\r\n");
1190
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_rcmd_nalu_size(sdp_ptr_, 1, 0, 1, nullptr));
1191
0
}
1192
1193
0
TEST_F(SdpTest, parseFmtpParameterAdd) {
1194
0
  ParseSdp(kVideoSdp + "a=fmtp:120 parameter-add=1\r\n");
1195
0
  ASSERT_EQ(1, sdp_attr_fmtp_is_parameter_add(sdp_ptr_, 1, 0, 1));
1196
0
}
1197
1198
0
TEST_F(SdpTest, parseFmtpParameterAddWith0) {
1199
0
  ParseSdp(kVideoSdp + "a=fmtp:120 parameter-add=0\r\n");
1200
0
  ASSERT_EQ(0, sdp_attr_fmtp_is_parameter_add(sdp_ptr_, 1, 0, 1));
1201
0
}
1202
1203
0
TEST_F(SdpTest, parseFmtpParameterAddWith2) {
1204
0
  ParseSdp(kVideoSdp + "a=fmtp:120 parameter-add=2\r\n");
1205
0
  ASSERT_EQ(0, sdp_attr_fmtp_is_parameter_add(sdp_ptr_, 1, 0, 1));
1206
0
}
1207
1208
0
TEST_F(SdpTest, parseFmtpAnnexK) {
1209
0
  ParseSdp(kVideoSdp + "a=fmtp:120 K=566\r\n");
1210
0
  ASSERT_EQ(566, sdp_attr_get_fmtp_annex_k_val(sdp_ptr_, 1, 0, 1));
1211
0
}
1212
1213
0
TEST_F(SdpTest, parseFmtpAnnexKWith0) {
1214
0
  ParseSdp(kVideoSdp + "a=fmtp:120 K=0\r\n");
1215
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_annex_k_val(sdp_ptr_, 1, 0, 1));
1216
0
}
1217
1218
0
TEST_F(SdpTest, parseFmtpAnnexKWith65536) {
1219
0
  ParseSdp(kVideoSdp + "a=fmtp:120 K=65536\r\n");
1220
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_annex_k_val(sdp_ptr_, 1, 0, 1));
1221
0
}
1222
1223
0
TEST_F(SdpTest, parseFmtpAnnexN) {
1224
0
  ParseSdp(kVideoSdp + "a=fmtp:120 N=4567\r\n");
1225
0
  ASSERT_EQ(4567, sdp_attr_get_fmtp_annex_n_val(sdp_ptr_, 1, 0, 1));
1226
0
}
1227
1228
0
TEST_F(SdpTest, parseFmtpAnnexNWith0) {
1229
0
  ParseSdp(kVideoSdp + "a=fmtp:120 N=0\r\n");
1230
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_annex_n_val(sdp_ptr_, 1, 0, 1));
1231
0
}
1232
1233
0
TEST_F(SdpTest, parseFmtpAnnexNWith65536) {
1234
0
  ParseSdp(kVideoSdp + "a=fmtp:120 N=65536\r\n");
1235
0
  ASSERT_EQ(SDP_INVALID_VALUE, sdp_attr_get_fmtp_annex_n_val(sdp_ptr_, 1, 0, 1));
1236
0
}
1237
1238
0
TEST_F(SdpTest, parseFmtpAnnexP) {
1239
0
  ParseSdp(kVideoSdp + "a=fmtp:120 P=5678,2\r\n");
1240
0
  ASSERT_EQ(5678, sdp_attr_get_fmtp_annex_p_picture_resize(sdp_ptr_, 1, 0, 1));
1241
0
  ASSERT_EQ(2, sdp_attr_get_fmtp_annex_p_warp(sdp_ptr_, 1, 0, 1));
1242
0
}
1243
1244
0
TEST_F(SdpTest, parseFmtpAnnexPWithResize0) {
1245
0
  ParseSdp(kVideoSdp + "a=fmtp:120 P=0,3\r\n");
1246
0
  ASSERT_EQ(0, sdp_attr_get_fmtp_annex_p_picture_resize(sdp_ptr_, 1, 0, 1));
1247
0
  ASSERT_EQ(3, sdp_attr_get_fmtp_annex_p_warp(sdp_ptr_, 1, 0, 1));
1248
0
}
1249
1250
0
TEST_F(SdpTest, parseFmtpAnnexPWithResize65536) {
1251
0
  ParseSdp(kVideoSdp + "a=fmtp:120 P=65536,4\r\n");
1252
0
  ASSERT_EQ(0, sdp_attr_get_fmtp_annex_p_picture_resize(sdp_ptr_, 1, 0, 1));
1253
0
  // if the first fails, the second will too.  Both default to 0 on failure.
1254
0
  ASSERT_EQ(0, sdp_attr_get_fmtp_annex_p_warp(sdp_ptr_, 1, 0, 1));
1255
0
}
1256
1257
0
TEST_F(SdpTest, parseFmtpAnnexPWithWarp65536) {
1258
0
  ParseSdp(kVideoSdp + "a=fmtp:120 P=346,65536\r\n");
1259
0
  ASSERT_EQ(346, sdp_attr_get_fmtp_annex_p_picture_resize(sdp_ptr_, 1, 0, 1));
1260
0
  ASSERT_EQ(0, sdp_attr_get_fmtp_annex_p_warp(sdp_ptr_, 1, 0, 1));
1261
0
}
1262
1263
0
TEST_F(SdpTest, parseFmtpLevelAsymmetryAllowed) {
1264
0
  ParseSdp(kVideoSdp + "a=fmtp:120 level-asymmetry-allowed=1\r\n");
1265
0
1266
0
  uint16_t levelAsymmetryAllowed;
1267
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_level_asymmetry_allowed(sdp_ptr_, 1, 0, 1, &levelAsymmetryAllowed));
1268
0
  ASSERT_EQ(1U, levelAsymmetryAllowed);
1269
0
}
1270
1271
0
TEST_F(SdpTest, parseFmtpLevelAsymmetryAllowedWith0) {
1272
0
  ParseSdp(kVideoSdp + "a=fmtp:120 level-asymmetry-allowed=0\r\n");
1273
0
  uint16_t levelAsymmetryAllowed;
1274
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_level_asymmetry_allowed(sdp_ptr_, 1, 0, 1, &levelAsymmetryAllowed));
1275
0
  ASSERT_EQ(0U, levelAsymmetryAllowed);
1276
0
}
1277
1278
0
TEST_F(SdpTest, parseFmtpLevelAsymmetryAllowedWith2) {
1279
0
  ParseSdp(kVideoSdp + "a=fmtp:120 level-asymmetry-allowed=2\r\n");
1280
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_level_asymmetry_allowed(sdp_ptr_, 1, 0, 1, nullptr));
1281
0
}
1282
1283
0
TEST_F(SdpTest, parseFmtpMaxAverageBitrate) {
1284
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxaveragebitrate=47893\r\n");
1285
0
  uint32_t maxAverageBitrate;
1286
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_max_average_bitrate(sdp_ptr_, 1, 0, 1, &maxAverageBitrate));
1287
0
  ASSERT_EQ(47893U, maxAverageBitrate);
1288
0
}
1289
1290
0
TEST_F(SdpTest, parseFmtpMaxAverageBitrateWith0) {
1291
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxaveragebitrate=0\r\n");
1292
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_average_bitrate(sdp_ptr_, 1, 0, 1, nullptr));
1293
0
}
1294
1295
0
TEST_F(SdpTest, parseFmtpMaxAverageBitrateWith4294967296) {
1296
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxaveragebitrate=4294967296\r\n");
1297
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_average_bitrate(sdp_ptr_, 1, 0, 1, nullptr));
1298
0
}
1299
1300
0
TEST_F(SdpTest, parseFmtpUsedTx) {
1301
0
  ParseSdp(kVideoSdp + "a=fmtp:120 usedtx=1\r\n");
1302
0
  tinybool usedTx;
1303
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_usedtx(sdp_ptr_, 1, 0, 1, &usedTx));
1304
0
  ASSERT_EQ(1, usedTx);
1305
0
}
1306
1307
0
TEST_F(SdpTest, parseFmtpUsedTxWith0) {
1308
0
  ParseSdp(kVideoSdp + "a=fmtp:120 usedtx=0\r\n");
1309
0
  tinybool usedTx;
1310
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_usedtx(sdp_ptr_, 1, 0, 1, &usedTx));
1311
0
  ASSERT_EQ(0, usedTx);
1312
0
}
1313
1314
0
TEST_F(SdpTest, parseFmtpUsedTxWith2) {
1315
0
  ParseSdp(kVideoSdp + "a=fmtp:120 usedtx=2\r\n");
1316
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_usedtx(sdp_ptr_, 1, 0, 1, nullptr));
1317
0
}
1318
1319
0
TEST_F(SdpTest, parseFmtpStereo) {
1320
0
  ParseSdp(kVideoSdp + "a=fmtp:120 stereo=1\r\n");
1321
0
  tinybool stereo;
1322
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_stereo(sdp_ptr_, 1, 0, 1, &stereo));
1323
0
  ASSERT_EQ(1, stereo);
1324
0
}
1325
1326
0
TEST_F(SdpTest, parseFmtpStereoWith0) {
1327
0
  ParseSdp(kVideoSdp + "a=fmtp:120 stereo=0\r\n");
1328
0
  tinybool stereo;
1329
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_stereo(sdp_ptr_, 1, 0, 1, &stereo));
1330
0
  ASSERT_EQ(0, stereo);
1331
0
}
1332
1333
0
TEST_F(SdpTest, parseFmtpStereoWith2) {
1334
0
  ParseSdp(kVideoSdp + "a=fmtp:120 stereo=2\r\n");
1335
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_stereo(sdp_ptr_, 1, 0, 1, nullptr));
1336
0
}
1337
1338
0
TEST_F(SdpTest, parseFmtpUseInBandFec) {
1339
0
  ParseSdp(kVideoSdp + "a=fmtp:120 useinbandfec=1\r\n");
1340
0
  tinybool useInbandFec;
1341
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_useinbandfec(sdp_ptr_, 1, 0, 1, &useInbandFec));
1342
0
  ASSERT_EQ(1, useInbandFec);
1343
0
}
1344
1345
0
TEST_F(SdpTest, parseFmtpUseInBandWith0) {
1346
0
  ParseSdp(kVideoSdp + "a=fmtp:120 useinbandfec=0\r\n");
1347
0
  tinybool useInbandFec;
1348
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_useinbandfec(sdp_ptr_, 1, 0, 1, &useInbandFec));
1349
0
  ASSERT_EQ(0, useInbandFec);
1350
0
}
1351
1352
0
TEST_F(SdpTest, parseFmtpUseInBandWith2) {
1353
0
  ParseSdp(kVideoSdp + "a=fmtp:120 useinbandfec=2\r\n");
1354
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_useinbandfec(sdp_ptr_, 1, 0, 1, nullptr));
1355
0
}
1356
1357
0
TEST_F(SdpTest, parseFmtpMaxCodedAudioBandwidth) {
1358
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxcodedaudiobandwidth=abcdefg\r\n");
1359
0
  char* maxCodedAudioBandwith = sdp_attr_get_fmtp_maxcodedaudiobandwidth(sdp_ptr_, 1, 0, 1);
1360
0
  ASSERT_EQ(0, strcmp("abcdefg", maxCodedAudioBandwith));
1361
0
}
1362
1363
0
TEST_F(SdpTest, parseFmtpMaxCodedAudioBandwidthBad) {
1364
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxcodedaudiobandwidth=\r\n");
1365
0
  char* maxCodedAudioBandwith = sdp_attr_get_fmtp_maxcodedaudiobandwidth(sdp_ptr_, 1, 0, 1);
1366
0
  ASSERT_EQ(0, *maxCodedAudioBandwith);
1367
0
}
1368
1369
0
TEST_F(SdpTest, parseFmtpCbr) {
1370
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cbr=1\r\n");
1371
0
  tinybool cbr;
1372
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_cbr(sdp_ptr_, 1, 0, 1, &cbr));
1373
0
  ASSERT_EQ(1, cbr);
1374
0
}
1375
1376
0
TEST_F(SdpTest, parseFmtpCbrWith0) {
1377
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cbr=0\r\n");
1378
0
  tinybool cbr;
1379
0
  ASSERT_EQ(SDP_SUCCESS, sdp_attr_get_fmtp_cbr(sdp_ptr_, 1, 0, 1, &cbr));
1380
0
  ASSERT_EQ(0, cbr);
1381
0
}
1382
1383
0
TEST_F(SdpTest, parseFmtpCbrWith2) {
1384
0
  ParseSdp(kVideoSdp + "a=fmtp:120 cbr=2\r\n");
1385
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_cbr(sdp_ptr_, 1, 0, 1, nullptr));
1386
0
}
1387
1388
0
TEST_F(SdpTest, parseFmtpMaxPlaybackRate) {
1389
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxplaybackrate=47900\r\n");
1390
0
  sdp_attr_t *attr_p = sdp_find_attr(sdp_ptr_, 1, 0, SDP_ATTR_FMTP, 1);
1391
0
  ASSERT_NE(nullptr, attr_p);
1392
0
  ASSERT_EQ(47900U, attr_p->attr.fmtp.maxplaybackrate);
1393
0
}
1394
1395
0
TEST_F(SdpTest, parseFmtpMaxPlaybackRateWith0) {
1396
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxplaybackrate=0\r\n");
1397
0
  sdp_attr_t *attr_p = sdp_find_attr(sdp_ptr_, 1, 0, SDP_ATTR_FMTP, 1);
1398
0
  ASSERT_EQ(NULL, attr_p);
1399
0
}
1400
1401
0
TEST_F(SdpTest, parseFmtpMaxPlaybackRateWith4294967296) {
1402
0
  ParseSdp(kVideoSdp + "a=fmtp:120 maxplaybackrate=4294967296\r\n");
1403
0
  sdp_attr_t *attr_p = sdp_find_attr(sdp_ptr_, 1, 0, SDP_ATTR_FMTP, 1);
1404
0
  ASSERT_EQ(NULL, attr_p);
1405
0
}
1406
1407
0
TEST_F(SdpTest, parseFmtpMaxFs) {
1408
0
  uint32_t val = 0;
1409
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=300;max-fr=30\r\n");
1410
0
  ASSERT_EQ(sdp_attr_get_fmtp_max_fs(sdp_ptr_, 1, 0, 1, &val), SDP_SUCCESS);
1411
0
  ASSERT_EQ(val, 300U);
1412
0
}
1413
0
TEST_F(SdpTest, parseFmtpMaxFsWith0) {
1414
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=0\r\n");
1415
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_fs(sdp_ptr_, 1, 0, 1, nullptr));
1416
0
}
1417
1418
0
TEST_F(SdpTest, parseFmtpMaxFsWith4294967296) {
1419
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=4294967296\r\n");
1420
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_fs(sdp_ptr_, 1, 0, 1, nullptr));
1421
0
}
1422
1423
0
TEST_F(SdpTest, parseFmtpMaxFr) {
1424
0
  uint32_t val = 0;
1425
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-fs=300;max-fr=30\r\n");
1426
0
  ASSERT_EQ(sdp_attr_get_fmtp_max_fr(sdp_ptr_, 1, 0, 1, &val), SDP_SUCCESS);
1427
0
  ASSERT_EQ(val, 30U);
1428
0
}
1429
1430
0
TEST_F(SdpTest, parseFmtpMaxFrWith0) {
1431
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-fr=0\r\n");
1432
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_fr(sdp_ptr_, 1, 0, 1, nullptr));
1433
0
}
1434
1435
0
TEST_F(SdpTest, parseFmtpMaxFrWith4294967296) {
1436
0
  ParseSdp(kVideoSdp + "a=fmtp:120 max-fr=4294967296\r\n");
1437
0
  ASSERT_EQ(SDP_INVALID_PARAMETER, sdp_attr_get_fmtp_max_fr(sdp_ptr_, 1, 0, 1, nullptr));
1438
0
}
1439
1440
0
TEST_F(SdpTest, addFmtpMaxFs) {
1441
0
  InitLocalSdp();
1442
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
1443
0
  AddNewFmtpMaxFs(level, 300);
1444
0
  std::string body = SerializeSdp();
1445
0
  ASSERT_NE(body.find("a=fmtp:120 max-fs=300\r\n"), std::string::npos);
1446
0
}
1447
1448
0
TEST_F(SdpTest, addFmtpMaxFr) {
1449
0
  InitLocalSdp();
1450
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
1451
0
  AddNewFmtpMaxFr(level, 30);
1452
0
  std::string body = SerializeSdp();
1453
0
  ASSERT_NE(body.find("a=fmtp:120 max-fr=30\r\n"), std::string::npos);
1454
0
}
1455
1456
0
TEST_F(SdpTest, addFmtpMaxFsFr) {
1457
0
  InitLocalSdp();
1458
0
  int level = AddNewMedia(SDP_MEDIA_VIDEO);
1459
0
  AddNewFmtpMaxFsFr(level, 300, 30);
1460
0
  std::string body = SerializeSdp();
1461
0
  ASSERT_NE(body.find("a=fmtp:120 max-fs=300;max-fr=30\r\n"),
1462
0
            std::string::npos);
1463
0
}
1464
1465
static const std::string kBrokenFmtp =
1466
  "v=0\r\n"
1467
  "o=- 4294967296 2 IN IP4 127.0.0.1\r\n"
1468
  "s=SIP Call\r\n"
1469
  "t=0 0\r\n"
1470
  "m=video 56436 RTP/SAVPF 120\r\n"
1471
  "c=IN IP4 198.51.100.7\r\n"
1472
  "a=rtpmap:120 VP8/90000\r\n"
1473
  /* Note: the \0 in this string triggered bz://1089207
1474
   */
1475
  "a=fmtp:120 max-fs=300;max\0fr=30";
1476
1477
0
TEST_F(SdpTest, parseBrokenFmtp) {
1478
0
  uint32_t val = 0;
1479
0
  const char *buf = kBrokenFmtp.data();
1480
0
  ResetSdp();
1481
0
  /* We need to manually invoke the parser here to be able to specify the length
1482
0
   * of the string beyond the \0 in last line of the string.
1483
0
   */
1484
0
  ASSERT_EQ(sdp_parse(sdp_ptr_, buf, 165), SDP_SUCCESS);
1485
0
  ASSERT_EQ(sdp_attr_get_fmtp_max_fs(sdp_ptr_, 1, 0, 1, &val), SDP_INVALID_PARAMETER);
1486
0
}
1487
1488
0
TEST_F(SdpTest, addIceLite) {
1489
0
    InitLocalSdp();
1490
0
    uint16_t inst_num = 0;
1491
0
    EXPECT_EQ(sdp_add_new_attr(sdp_ptr_, SDP_SESSION_LEVEL, 0,
1492
0
                               SDP_ATTR_ICE_LITE, &inst_num), SDP_SUCCESS);
1493
0
    std::string body = SerializeSdp();
1494
0
    ASSERT_NE(body.find("a=ice-lite\r\n"), std::string::npos);
1495
0
}
1496
1497
0
TEST_F(SdpTest, parseIceLite) {
1498
0
    std::string sdp =
1499
0
        "v=0\r\n"
1500
0
        "o=- 4294967296 2 IN IP4 127.0.0.1\r\n"
1501
0
        "s=SIP Call\r\n"
1502
0
        "t=0 0\r\n"
1503
0
        "a=ice-lite\r\n";
1504
0
  ParseSdp(sdp);
1505
0
  ASSERT_TRUE(sdp_attr_is_present(sdp_ptr_, SDP_ATTR_ICE_LITE,
1506
0
                                  SDP_SESSION_LEVEL, 0));
1507
0
}
1508
1509
class NewSdpTest : public ::testing::Test,
1510
                   public ::testing::WithParamInterface<
1511
                     ::testing::tuple<bool, bool> > {
1512
  public:
1513
0
    NewSdpTest() : mSdpErrorHolder(nullptr) {
1514
0
    }
1515
1516
0
    void ParseSdp(const std::string &sdp, bool expectSuccess = true) {
1517
0
      if (::testing::get<1>(GetParam())) {
1518
0
        mSdpErrorHolder = &mSipccParser;
1519
0
        mSdp = mSipccParser.Parse(sdp);
1520
0
      } else {
1521
0
        mSdpErrorHolder = &mRustParser;
1522
0
        mSdp = mRustParser.Parse(sdp);
1523
0
      }
1524
0
1525
0
      // Are we configured to do a parse and serialize before actually
1526
0
      // running the test?
1527
0
      if (::testing::get<0>(GetParam())) {
1528
0
        std::stringstream os;
1529
0
1530
0
        if (expectSuccess) {
1531
0
          ASSERT_TRUE(!!mSdp) << "Parse failed on first pass: "
1532
0
                              << GetParseErrors();
1533
0
        }
1534
0
1535
0
        if (mSdp) {
1536
0
          // Serialize and re-parse
1537
0
          mSdp->Serialize(os);
1538
0
          if (::testing::get<1>(GetParam())) {
1539
0
            mSdp = mSipccParser.Parse(os.str());
1540
0
          } else {
1541
0
            mSdp = mRustParser.Parse(os.str());
1542
0
          }
1543
0
1544
0
          // Whether we expected the parse to work or not, it should
1545
0
          // succeed the second time if it succeeded the first.
1546
0
          ASSERT_TRUE(!!mSdp) << "Parse failed on second pass, SDP was: "
1547
0
            << std::endl << os.str() <<  std::endl
1548
0
            << "Errors were: " << GetParseErrors();
1549
0
1550
0
          // Serialize again and compare
1551
0
          std::stringstream os2;
1552
0
          mSdp->Serialize(os2);
1553
0
          ASSERT_EQ(os.str(), os2.str());
1554
0
        }
1555
0
      }
1556
0
1557
0
      if (expectSuccess) {
1558
0
        ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
1559
0
        ASSERT_EQ(0U, mSdpErrorHolder->GetParseErrors().size())
1560
0
                  << "Got unexpected parse errors/warnings: "
1561
0
                  << GetParseErrors();
1562
0
      }
1563
0
    }
1564
1565
    // For streaming parse errors
1566
0
    std::string GetParseErrors() const {
1567
0
      std::stringstream output;
1568
0
      for (auto e: mSdpErrorHolder->GetParseErrors()) {
1569
0
        output << e.first << ": " << e.second << std::endl;
1570
0
      }
1571
0
      return output.str();
1572
0
    }
1573
1574
0
    std::string GetParseWarnings() const {
1575
0
      std::stringstream output;
1576
0
      for (auto e: mSdpErrorHolder->GetParseWarnings()) {
1577
0
        output << e.first << ": " << e.second << std::endl;
1578
0
      }
1579
0
      return output.str();
1580
0
    }
1581
1582
    void CheckRtpmap(const std::string& expected_pt,
1583
                     SdpRtpmapAttributeList::CodecType codec,
1584
                     const std::string& name,
1585
                     uint32_t clock,
1586
                     uint16_t channels,
1587
                     const std::string& search_pt,
1588
0
                     const SdpRtpmapAttributeList& rtpmaps) const {
1589
0
      ASSERT_TRUE(rtpmaps.HasEntry(search_pt));
1590
0
      auto attr = rtpmaps.GetEntry(search_pt);
1591
0
      ASSERT_EQ(expected_pt, attr.pt);
1592
0
      ASSERT_EQ(codec, attr.codec);
1593
0
      ASSERT_EQ(name, attr.name);
1594
0
      ASSERT_EQ(clock, attr.clock);
1595
0
      ASSERT_EQ(channels, attr.channels);
1596
0
    }
1597
1598
    void CheckSctpmap(const std::string& expected_pt,
1599
                      const std::string& name,
1600
                      uint16_t streams,
1601
                      const std::string& search_pt,
1602
0
                      const SdpSctpmapAttributeList& sctpmaps) const {
1603
0
      ASSERT_TRUE(sctpmaps.HasEntry(search_pt));
1604
0
      auto attr = sctpmaps.GetFirstEntry();
1605
0
      ASSERT_EQ(expected_pt, search_pt);
1606
0
      ASSERT_EQ(expected_pt, attr.pt);
1607
0
      ASSERT_EQ(name, attr.name);
1608
0
      ASSERT_EQ(streams, attr.streams);
1609
0
    }
1610
1611
    void CheckRtcpFb(const SdpRtcpFbAttributeList::Feedback& feedback,
1612
                     const std::string& pt,
1613
                     SdpRtcpFbAttributeList::Type type,
1614
                     const std::string& first_parameter,
1615
0
                     const std::string& extra = "") const {
1616
0
      ASSERT_EQ(pt, feedback.pt);
1617
0
      ASSERT_EQ(type, feedback.type);
1618
0
      ASSERT_EQ(first_parameter, feedback.parameter);
1619
0
      ASSERT_EQ(extra, feedback.extra);
1620
0
    }
1621
1622
0
    void CheckDtmfFmtp(const std::string& expectedDtmfTones) const {
1623
0
      ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
1624
0
                  SdpAttribute::kFmtpAttribute));
1625
0
      auto audio_format_params =
1626
0
          mSdp->GetMediaSection(0).GetAttributeList().GetFmtp().mFmtps;
1627
0
      ASSERT_EQ(2U, audio_format_params.size());
1628
0
1629
0
      ASSERT_EQ("101", audio_format_params[1].format);
1630
0
      ASSERT_TRUE(!!audio_format_params[1].parameters);
1631
0
      const SdpFmtpAttributeList::TelephoneEventParameters* te_parameters =
1632
0
        static_cast<SdpFmtpAttributeList::TelephoneEventParameters*>(
1633
0
            audio_format_params[1].parameters.get());
1634
0
      ASSERT_NE(0U, te_parameters->dtmfTones.size());
1635
0
      ASSERT_EQ(expectedDtmfTones, te_parameters->dtmfTones);
1636
0
    }
1637
1638
    void CheckSerialize(const std::string& expected,
1639
0
                        const SdpAttribute& attr) const {
1640
0
      std::stringstream str;
1641
0
      attr.Serialize(str);
1642
0
      ASSERT_EQ(expected, str.str());
1643
0
    }
1644
1645
0
    bool IsParsingWithSipccParser() const {
1646
0
      return ::testing::get<1>(GetParam());
1647
0
    }
1648
1649
    SdpErrorHolder* mSdpErrorHolder;
1650
    SipccSdpParser mSipccParser;
1651
    RsdparsaSdpParser mRustParser;
1652
    mozilla::UniquePtr<Sdp> mSdp;
1653
}; // class NewSdpTest
1654
1655
0
TEST_P(NewSdpTest, CreateDestroy) {
1656
0
}
1657
1658
0
TEST_P(NewSdpTest, ParseEmpty) {
1659
0
  ParseSdp("", false);
1660
0
  ASSERT_FALSE(mSdp);
1661
0
  ASSERT_NE(0U, mSdpErrorHolder->GetParseErrors().size())
1662
0
    << "Expected at least one parse error.";
1663
0
}
1664
1665
const std::string kBadSdp = "This is SDPARTA!!!!";
1666
1667
0
TEST_P(NewSdpTest, ParseGarbage) {
1668
0
  ParseSdp(kBadSdp, false);
1669
0
  ASSERT_FALSE(mSdp);
1670
0
  ASSERT_NE(0U, mSdpErrorHolder->GetParseErrors().size())
1671
0
    << "Expected at least one parse error.";
1672
0
}
1673
1674
0
TEST_P(NewSdpTest, ParseGarbageTwice) {
1675
0
  ParseSdp(kBadSdp, false);
1676
0
  ASSERT_FALSE(mSdp);
1677
0
  size_t errorCount = mSdpErrorHolder->GetParseErrors().size();
1678
0
  ASSERT_NE(0U, errorCount)
1679
0
    << "Expected at least one parse error.";
1680
0
  ParseSdp(kBadSdp, false);
1681
0
  ASSERT_FALSE(mSdp);
1682
0
  ASSERT_EQ(errorCount, mSdpErrorHolder->GetParseErrors().size())
1683
0
    << "Expected same error count for same SDP.";
1684
0
}
1685
1686
0
TEST_P(NewSdpTest, ParseMinimal) {
1687
0
  ParseSdp(kVideoSdp);
1688
0
  ASSERT_EQ(0U, mSdpErrorHolder->GetParseErrors().size()) <<
1689
0
    "Got parse errors: " << GetParseErrors();
1690
0
}
1691
1692
0
TEST_P(NewSdpTest, CheckOriginGetUsername) {
1693
0
  ParseSdp(kVideoSdp);
1694
0
  ASSERT_EQ("-", mSdp->GetOrigin().GetUsername())
1695
0
    << "Wrong username in origin";
1696
0
}
1697
1698
0
TEST_P(NewSdpTest, CheckOriginGetSessionId) {
1699
0
  ParseSdp(kVideoSdp);
1700
0
  ASSERT_EQ(4294967296U, mSdp->GetOrigin().GetSessionId())
1701
0
    << "Wrong session id in origin";
1702
0
}
1703
1704
0
TEST_P(NewSdpTest, CheckOriginGetSessionVersion) {
1705
0
  ParseSdp(kVideoSdp);
1706
0
  ASSERT_EQ(2U , mSdp->GetOrigin().GetSessionVersion())
1707
0
    << "Wrong version in origin";
1708
0
}
1709
1710
0
TEST_P(NewSdpTest, CheckOriginGetAddrType) {
1711
0
  ParseSdp(kVideoSdp);
1712
0
  ASSERT_EQ(sdp::kIPv4, mSdp->GetOrigin().GetAddrType())
1713
0
    << "Wrong address type in origin";
1714
0
}
1715
1716
0
TEST_P(NewSdpTest, CheckOriginGetAddress) {
1717
0
  ParseSdp(kVideoSdp);
1718
0
  ASSERT_EQ("127.0.0.1" , mSdp->GetOrigin().GetAddress())
1719
0
    << "Wrong address in origin";
1720
0
}
1721
1722
0
TEST_P(NewSdpTest, CheckGetMissingBandwidth) {
1723
0
  ParseSdp(kVideoSdp);
1724
0
  ASSERT_EQ(0U, mSdp->GetBandwidth("CT"))
1725
0
    << "Wrong bandwidth in session";
1726
0
}
1727
1728
0
TEST_P(NewSdpTest, CheckGetBandwidth) {
1729
0
  ParseSdp("v=0" CRLF
1730
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
1731
0
           "s=SIP Call" CRLF
1732
0
           "c=IN IP4 198.51.100.7" CRLF
1733
0
           "b=CT:5000" CRLF
1734
0
           "b=FOOBAR:10" CRLF
1735
0
           "b=AS:4" CRLF
1736
0
           "t=0 0" CRLF
1737
0
           "m=video 56436 RTP/SAVPF 120" CRLF
1738
0
           "a=rtpmap:120 VP8/90000" CRLF
1739
0
           );
1740
0
  ASSERT_EQ(5000U, mSdp->GetBandwidth("CT"))
1741
0
    << "Wrong CT bandwidth in session";
1742
0
  ASSERT_EQ(0U, mSdp->GetBandwidth("FOOBAR"))
1743
0
    << "Wrong FOOBAR bandwidth in session";
1744
0
  ASSERT_EQ(4U, mSdp->GetBandwidth("AS"))
1745
0
    << "Wrong AS bandwidth in session";
1746
0
}
1747
1748
0
TEST_P(NewSdpTest, CheckGetMediaSectionsCount) {
1749
0
  ParseSdp(kVideoSdp);
1750
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
1751
0
    << "Wrong number of media sections";
1752
0
}
1753
1754
0
TEST_P(NewSdpTest, CheckMediaSectionGetMediaType) {
1755
0
  ParseSdp(kVideoSdp);
1756
0
  ASSERT_EQ(SdpMediaSection::kVideo, mSdp->GetMediaSection(0).GetMediaType())
1757
0
    << "Wrong type for first media section";
1758
0
}
1759
1760
0
TEST_P(NewSdpTest, CheckMediaSectionGetProtocol) {
1761
0
  ParseSdp(kVideoSdp);
1762
0
  ASSERT_EQ(SdpMediaSection::kRtpSavpf, mSdp->GetMediaSection(0).GetProtocol())
1763
0
    << "Wrong protocol for video";
1764
0
}
1765
1766
0
TEST_P(NewSdpTest, CheckMediaSectionGetFormats) {
1767
0
  ParseSdp(kVideoSdp);
1768
0
  auto video_formats = mSdp->GetMediaSection(0).GetFormats();
1769
0
  ASSERT_EQ(1U, video_formats.size()) << "Wrong number of formats for video";
1770
0
  ASSERT_EQ("120", video_formats[0]);
1771
0
}
1772
1773
0
TEST_P(NewSdpTest, CheckMediaSectionGetPort) {
1774
0
  ParseSdp(kVideoSdp);
1775
0
  ASSERT_EQ(56436U, mSdp->GetMediaSection(0).GetPort())
1776
0
    << "Wrong port number in media section";
1777
0
}
1778
1779
0
TEST_P(NewSdpTest, CheckMediaSectionGetMissingPortCount) {
1780
0
  ParseSdp(kVideoSdp);
1781
0
  ASSERT_EQ(0U, mSdp->GetMediaSection(0).GetPortCount())
1782
0
    << "Wrong port count in media section";
1783
0
}
1784
1785
0
TEST_P(NewSdpTest, CheckMediaSectionGetPortCount) {
1786
0
  ParseSdp(kVideoSdp +
1787
0
      "m=audio 12345/2 RTP/SAVPF 0" CRLF
1788
0
      "a=rtpmap:0 PCMU/8000" CRLF
1789
0
      );
1790
0
  ASSERT_EQ(2U, mSdp->GetMediaSectionCount())
1791
0
    << "Wrong number of media sections";
1792
0
  ASSERT_EQ(2U, mSdp->GetMediaSection(1).GetPortCount())
1793
0
    << "Wrong port count in media section";
1794
0
}
1795
1796
0
TEST_P(NewSdpTest, CheckMediaSectionGetMissingBandwidth) {
1797
0
  ParseSdp(kVideoSdp);
1798
0
  ASSERT_EQ(0U, mSdp->GetMediaSection(0).GetBandwidth("CT"))
1799
0
    << "Wrong bandwidth in media section";
1800
0
}
1801
1802
0
TEST_P(NewSdpTest, CheckMediaSectionGetBandwidth) {
1803
0
  ParseSdp("v=0\r\n"
1804
0
           "o=- 4294967296 2 IN IP4 127.0.0.1\r\n"
1805
0
           "s=SIP Call\r\n"
1806
0
           "c=IN IP4 198.51.100.7\r\n"
1807
0
           "t=0 0\r\n"
1808
0
           "m=video 56436 RTP/SAVPF 120\r\n"
1809
0
           "b=CT:1000\r\n"
1810
0
           "a=rtpmap:120 VP8/90000\r\n");
1811
0
  ASSERT_EQ(1000U, mSdp->GetMediaSection(0).GetBandwidth("CT"))
1812
0
    << "Wrong bandwidth in media section";
1813
0
}
1814
1815
// Define a string that is 258 characters long. We use a long string here so
1816
// that we can test that we are able to parse and handle a string longer than
1817
// the default maximum length of 256 in sipcc.
1818
#define ID_A "1234567890abcdef"
1819
#define ID_B ID_A ID_A ID_A ID_A
1820
#define LONG_IDENTITY ID_B ID_B ID_B ID_B "xx"
1821
1822
#define BASE64_DTLS_HELLO "FgEAAAAAAAAAAAAAagEAAF4AAAAAAAAAXgEARI11KHx3QB6Ky" \
1823
  "CKgoBj/kwjKrApkL8kiZLwIqBaJGT8AAAA2ADkAOAA1ABYAEwAKADMAMgAvAAcAZgAFAAQAYw" \
1824
  "BiAGEAFQASAAkAZQBkAGAAFAARAAgABgADAQA="
1825
1826
// SDP from a basic A/V apprtc call FFX/FFX
1827
const std::string kBasicAudioVideoOffer =
1828
"v=0" CRLF
1829
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
1830
"s=SIP Call" CRLF
1831
"c=IN IP4 224.0.0.1/100/12" CRLF
1832
"t=0 0" CRLF
1833
"a=dtls-message:client " BASE64_DTLS_HELLO CRLF
1834
"a=ice-ufrag:4a799b2e" CRLF
1835
"a=ice-pwd:e4cc12a910f106a0a744719425510e17" CRLF
1836
"a=ice-lite" CRLF
1837
"a=ice-options:trickle foo" CRLF
1838
"a=msid-semantic:WMS stream streama" CRLF
1839
"a=msid-semantic:foo stream" CRLF
1840
"a=fingerprint:sha-256 DF:2E:AC:8A:FD:0A:8E:99:BF:5D:E8:3C:E7:FA:FB:08:3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C" CRLF
1841
"a=identity:" LONG_IDENTITY CRLF
1842
"a=group:BUNDLE first second" CRLF
1843
"a=group:BUNDLE third" CRLF
1844
"a=group:LS first third" CRLF
1845
"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF
1846
"c=IN IP4 0.0.0.0" CRLF
1847
"a=mid:first" CRLF
1848
"a=rtpmap:109 opus/48000/2" CRLF
1849
"a=fmtp:109 maxplaybackrate=32000;stereo=1" CRLF
1850
"a=ptime:20" CRLF
1851
"a=maxptime:20" CRLF
1852
"a=rtpmap:9 G722/8000" CRLF
1853
"a=rtpmap:0 PCMU/8000" CRLF
1854
"a=rtpmap:8 PCMA/8000" CRLF
1855
"a=rtpmap:101 telephone-event/8000" CRLF
1856
"a=fmtp:101 0-15,66,32-34,67" CRLF
1857
"a=ice-ufrag:00000000" CRLF
1858
"a=ice-pwd:0000000000000000000000000000000" CRLF
1859
"a=sendonly" CRLF
1860
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level" CRLF
1861
"a=setup:actpass" CRLF
1862
"a=rtcp-mux" CRLF
1863
"a=msid:stream track" CRLF
1864
"a=candidate:0 1 UDP 2130379007 10.0.0.36 62453 typ host" CRLF
1865
"a=candidate:2 1 UDP 1694236671 24.6.134.204 62453 typ srflx raddr 10.0.0.36 rport 62453" CRLF
1866
"a=candidate:3 1 UDP 100401151 162.222.183.171 49761 typ relay raddr 162.222.183.171 rport 49761" CRLF
1867
"a=candidate:6 1 UDP 16515071 162.222.183.171 51858 typ relay raddr 162.222.183.171 rport 51858" CRLF
1868
"a=candidate:3 2 UDP 100401150 162.222.183.171 62454 typ relay raddr 162.222.183.171 rport 62454" CRLF
1869
"a=candidate:2 2 UDP 1694236670 24.6.134.204 55428 typ srflx raddr 10.0.0.36 rport 55428" CRLF
1870
"a=candidate:6 2 UDP 16515070 162.222.183.171 50340 typ relay raddr 162.222.183.171 rport 50340" CRLF
1871
"a=candidate:0 2 UDP 2130379006 10.0.0.36 55428 typ host" CRLF
1872
"a=rtcp:62454 IN IP4 162.222.183.171" CRLF
1873
"a=end-of-candidates" CRLF
1874
"a=ssrc:5150" CRLF
1875
"m=video 9 RTP/SAVPF 120 121 122 123" CRLF
1876
"c=IN IP6 ::1" CRLF
1877
"a=fingerprint:sha-1 DF:FA:FB:08:3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C" CRLF
1878
"a=mid:second" CRLF
1879
"a=rtpmap:120 VP8/90000" CRLF
1880
"a=fmtp:120 max-fs=3600;max-fr=30" CRLF
1881
"a=rtpmap:121 VP9/90000" CRLF
1882
"a=fmtp:121 max-fs=3600;max-fr=30" CRLF
1883
"a=rtpmap:122 red/90000" CRLF
1884
"a=rtpmap:123 ulpfec/90000" CRLF
1885
"a=recvonly" CRLF
1886
"a=rtcp-fb:120 nack" CRLF
1887
"a=rtcp-fb:120 nack pli" CRLF
1888
"a=rtcp-fb:120 ccm fir" CRLF
1889
"a=rtcp-fb:121 nack" CRLF
1890
"a=rtcp-fb:121 nack pli" CRLF
1891
"a=rtcp-fb:121 ccm fir" CRLF
1892
"a=setup:active" CRLF
1893
"a=rtcp-mux" CRLF
1894
"a=msid:streama tracka" CRLF
1895
"a=msid:streamb trackb" CRLF
1896
"a=candidate:0 1 UDP 2130379007 10.0.0.36 59530 typ host" CRLF
1897
"a=candidate:0 2 UDP 2130379006 10.0.0.36 64378 typ host" CRLF
1898
"a=candidate:2 2 UDP 1694236670 24.6.134.204 64378 typ srflx raddr 10.0.0.36 rport 64378" CRLF
1899
"a=candidate:6 2 UDP 16515070 162.222.183.171 64941 typ relay raddr 162.222.183.171 rport 64941" CRLF
1900
"a=candidate:6 1 UDP 16515071 162.222.183.171 64800 typ relay raddr 162.222.183.171 rport 64800" CRLF
1901
"a=candidate:2 1 UDP 1694236671 24.6.134.204 59530 typ srflx raddr 10.0.0.36 rport 59530" CRLF
1902
"a=candidate:3 1 UDP 100401151 162.222.183.171 62935 typ relay raddr 162.222.183.171 rport 62935" CRLF
1903
"a=candidate:3 2 UDP 100401150 162.222.183.171 61026 typ relay raddr 162.222.183.171 rport 61026" CRLF
1904
"a=rtcp:61026" CRLF
1905
"a=end-of-candidates" CRLF
1906
"a=ssrc:1111 foo" CRLF
1907
"a=ssrc:1111 foo:bar" CRLF
1908
"a=ssrc:1111 msid:1d0cdb4e-5934-4f0f-9f88-40392cb60d31 315b086a-5cb6-4221-89de-caf0b038c79d" CRLF
1909
"a=imageattr:120 send * recv *" CRLF
1910
"a=imageattr:121 send [x=640,y=480] recv [x=640,y=480]" CRLF
1911
"a=rid:bar recv pt=120;max-width=800;max-height=600" CRLF
1912
"a=rid:bar123 recv max-width=1920;max-height=1080" CRLF
1913
"a=simulcast:recv rid=bar;bar123" CRLF
1914
"m=audio 9 RTP/SAVPF 0" CRLF
1915
"a=mid:third" CRLF
1916
"a=rtpmap:0 PCMU/8000" CRLF
1917
"a=ice-options:foo bar" CRLF
1918
"a=msid:noappdata" CRLF
1919
"a=bundle-only" CRLF;
1920
1921
0
TEST_P(NewSdpTest, BasicAudioVideoSdpParse) {
1922
0
  ParseSdp(kBasicAudioVideoOffer);
1923
0
}
1924
1925
0
TEST_P(NewSdpTest, CheckRemoveFmtp) {
1926
0
  ParseSdp(kBasicAudioVideoOffer);
1927
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
1928
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
1929
0
    << "Wrong number of media sections";
1930
0
1931
0
  SdpAttributeList& audioAttrList = mSdp->GetMediaSection(0).GetAttributeList();
1932
0
1933
0
  ASSERT_TRUE(audioAttrList.HasAttribute(SdpAttribute::kFmtpAttribute));
1934
0
  ASSERT_EQ(2U, audioAttrList.GetFmtp().mFmtps.size());
1935
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).FindFmtp("109"));
1936
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).FindFmtp("101"));
1937
0
1938
0
  mSdp->GetMediaSection(0).RemoveFmtp("101");
1939
0
1940
0
  ASSERT_TRUE(audioAttrList.HasAttribute(SdpAttribute::kFmtpAttribute));
1941
0
  ASSERT_EQ(1U, audioAttrList.GetFmtp().mFmtps.size());
1942
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).FindFmtp("109"));
1943
0
  ASSERT_FALSE(mSdp->GetMediaSection(0).FindFmtp("101"));
1944
0
1945
0
  mSdp->GetMediaSection(0).RemoveFmtp("109");
1946
0
1947
0
  ASSERT_TRUE(audioAttrList.HasAttribute(SdpAttribute::kFmtpAttribute));
1948
0
  ASSERT_EQ(0U, audioAttrList.GetFmtp().mFmtps.size());
1949
0
  ASSERT_FALSE(mSdp->GetMediaSection(0).FindFmtp("109"));
1950
0
  ASSERT_FALSE(mSdp->GetMediaSection(0).FindFmtp("101"));
1951
0
1952
0
  // make sure we haven't disturbed the video fmtps
1953
0
  SdpAttributeList& videoAttrList = mSdp->GetMediaSection(1).GetAttributeList();
1954
0
  ASSERT_TRUE(videoAttrList.HasAttribute(SdpAttribute::kFmtpAttribute));
1955
0
  ASSERT_EQ(2U, videoAttrList.GetFmtp().mFmtps.size());
1956
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).FindFmtp("120"));
1957
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).FindFmtp("121"));
1958
0
}
1959
1960
0
TEST_P(NewSdpTest, CheckIceUfrag) {
1961
0
  ParseSdp(kBasicAudioVideoOffer);
1962
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
1963
0
  ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
1964
0
        SdpAttribute::kIceUfragAttribute));
1965
0
  auto ice_ufrag = mSdp->GetAttributeList().GetIceUfrag();
1966
0
  ASSERT_EQ("4a799b2e", ice_ufrag) << "Wrong ice-ufrag value";
1967
0
1968
0
  ice_ufrag = mSdp->GetMediaSection(0)
1969
0
      .GetAttributeList().GetIceUfrag();
1970
0
  ASSERT_EQ("00000000", ice_ufrag) << "ice-ufrag isn't overridden";
1971
0
1972
0
  ice_ufrag = mSdp->GetMediaSection(1)
1973
0
      .GetAttributeList().GetIceUfrag();
1974
0
  ASSERT_EQ("4a799b2e", ice_ufrag) << "ice-ufrag isn't carried to m-section";
1975
0
}
1976
1977
0
TEST_P(NewSdpTest, CheckIcePwd) {
1978
0
  ParseSdp(kBasicAudioVideoOffer);
1979
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
1980
0
  ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
1981
0
        SdpAttribute::kIcePwdAttribute));
1982
0
  auto ice_pwd = mSdp->GetAttributeList().GetIcePwd();
1983
0
  ASSERT_EQ("e4cc12a910f106a0a744719425510e17", ice_pwd) << "Wrong ice-pwd value";
1984
0
1985
0
  ice_pwd = mSdp->GetMediaSection(0)
1986
0
      .GetAttributeList().GetIcePwd();
1987
0
  ASSERT_EQ("0000000000000000000000000000000", ice_pwd)
1988
0
      << "ice-pwd isn't overridden";
1989
0
1990
0
  ice_pwd = mSdp->GetMediaSection(1)
1991
0
      .GetAttributeList().GetIcePwd();
1992
0
  ASSERT_EQ("e4cc12a910f106a0a744719425510e17", ice_pwd)
1993
0
      << "ice-pwd isn't carried to m-section";
1994
0
}
1995
1996
0
TEST_P(NewSdpTest, CheckIceOptions) {
1997
0
  ParseSdp(kBasicAudioVideoOffer);
1998
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
1999
0
  ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
2000
0
        SdpAttribute::kIceOptionsAttribute));
2001
0
  auto ice_options = mSdp->GetAttributeList().GetIceOptions();
2002
0
  ASSERT_EQ(2U, ice_options.mValues.size()) << "Wrong ice-options size";
2003
0
  ASSERT_EQ("trickle", ice_options.mValues[0]) << "Wrong ice-options value";
2004
0
  ASSERT_EQ("foo", ice_options.mValues[1]) << "Wrong ice-options value";
2005
0
2006
0
  ASSERT_TRUE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
2007
0
        SdpAttribute::kIceOptionsAttribute));
2008
0
  auto ice_options_media_level =
2009
0
    mSdp->GetMediaSection(2).GetAttributeList().GetIceOptions();
2010
0
  ASSERT_EQ(2U, ice_options_media_level.mValues.size()) << "Wrong ice-options size";
2011
0
  ASSERT_EQ("foo", ice_options_media_level.mValues[0]) << "Wrong ice-options value";
2012
0
  ASSERT_EQ("bar", ice_options_media_level.mValues[1]) << "Wrong ice-options value";
2013
0
}
2014
2015
0
TEST_P(NewSdpTest, CheckFingerprint) {
2016
0
  ParseSdp(kBasicAudioVideoOffer);
2017
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2018
0
  ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
2019
0
        SdpAttribute::kFingerprintAttribute));
2020
0
  auto fingerprints = mSdp->GetAttributeList().GetFingerprint();
2021
0
  ASSERT_EQ(1U, fingerprints.mFingerprints.size());
2022
0
  ASSERT_EQ(SdpFingerprintAttributeList::kSha256,
2023
0
      fingerprints.mFingerprints[0].hashFunc)
2024
0
    << "Wrong hash function";
2025
0
  ASSERT_EQ("DF:2E:AC:8A:FD:0A:8E:99:BF:5D:E8:3C:E7:FA:FB:08:"
2026
0
            "3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C",
2027
0
            SdpFingerprintAttributeList::FormatFingerprint(
2028
0
                fingerprints.mFingerprints[0].fingerprint))
2029
0
    << "Wrong fingerprint";
2030
0
  ASSERT_EQ(0xdfU, fingerprints.mFingerprints[0].fingerprint[0])
2031
0
      << "first fingerprint element is iffy";
2032
0
2033
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount());
2034
0
2035
0
  // Fallback to session level
2036
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2037
0
        SdpAttribute::kFingerprintAttribute));
2038
0
  fingerprints = mSdp->GetMediaSection(0).GetAttributeList().GetFingerprint();
2039
0
  ASSERT_EQ(1U, fingerprints.mFingerprints.size());
2040
0
  ASSERT_EQ(SdpFingerprintAttributeList::kSha256,
2041
0
      fingerprints.mFingerprints[0].hashFunc)
2042
0
    << "Wrong hash function";
2043
0
  ASSERT_EQ("DF:2E:AC:8A:FD:0A:8E:99:BF:5D:E8:3C:E7:FA:FB:08:"
2044
0
            "3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C",
2045
0
            SdpFingerprintAttributeList::FormatFingerprint(
2046
0
                fingerprints.mFingerprints[0].fingerprint))
2047
0
    << "Wrong fingerprint";
2048
0
  ASSERT_EQ(0xdfU, fingerprints.mFingerprints[0].fingerprint[0])
2049
0
      << "first fingerprint element is iffy";
2050
0
2051
0
  // Media level
2052
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2053
0
        SdpAttribute::kFingerprintAttribute));
2054
0
  fingerprints = mSdp->GetMediaSection(1).GetAttributeList().GetFingerprint();
2055
0
  ASSERT_EQ(1U, fingerprints.mFingerprints.size());
2056
0
  ASSERT_EQ(SdpFingerprintAttributeList::kSha1,
2057
0
      fingerprints.mFingerprints[0].hashFunc)
2058
0
    << "Wrong hash function";
2059
0
  ASSERT_EQ("DF:FA:FB:08:3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:"
2060
0
            "08:6D:0F:4C",
2061
0
            SdpFingerprintAttributeList::FormatFingerprint(
2062
0
                fingerprints.mFingerprints[0].fingerprint))
2063
0
    << "Wrong fingerprint";
2064
0
  ASSERT_EQ(0xdfU, fingerprints.mFingerprints[0].fingerprint[0])
2065
0
      << "first fingerprint element is iffy";
2066
0
}
2067
2068
0
TEST_P(NewSdpTest, CheckIdentity) {
2069
0
  ParseSdp(kBasicAudioVideoOffer);
2070
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2071
0
  ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
2072
0
        SdpAttribute::kIdentityAttribute));
2073
0
  auto identity = mSdp->GetAttributeList().GetIdentity();
2074
0
  ASSERT_EQ(LONG_IDENTITY, identity) << "Wrong identity assertion";
2075
0
}
2076
2077
0
TEST_P(NewSdpTest, CheckDtlsMessage) {
2078
0
  ParseSdp(kBasicAudioVideoOffer);
2079
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2080
0
  ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
2081
0
        SdpAttribute::kDtlsMessageAttribute));
2082
0
  auto dtls_message = mSdp->GetAttributeList().GetDtlsMessage();
2083
0
  ASSERT_EQ(SdpDtlsMessageAttribute::kClient, dtls_message.mRole)
2084
0
    << "Wrong dtls-message role";
2085
0
  ASSERT_EQ(BASE64_DTLS_HELLO, dtls_message.mValue)
2086
0
    << "Wrong dtls-message value";
2087
0
}
2088
2089
0
TEST_P(NewSdpTest, CheckNumberOfMediaSections) {
2090
0
  ParseSdp(kBasicAudioVideoOffer);
2091
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2092
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
2093
0
}
2094
2095
0
TEST_P(NewSdpTest, CheckMlines) {
2096
0
  ParseSdp(kBasicAudioVideoOffer);
2097
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2098
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
2099
0
  ASSERT_EQ(SdpMediaSection::kAudio, mSdp->GetMediaSection(0).GetMediaType())
2100
0
    << "Wrong type for first media section";
2101
0
  ASSERT_EQ(SdpMediaSection::kRtpSavpf,
2102
0
            mSdp->GetMediaSection(0).GetProtocol())
2103
0
    << "Wrong protocol for audio";
2104
0
  auto audio_formats = mSdp->GetMediaSection(0).GetFormats();
2105
0
  ASSERT_EQ(5U, audio_formats.size()) << "Wrong number of formats for audio";
2106
0
  ASSERT_EQ("109", audio_formats[0]);
2107
0
  ASSERT_EQ("9",   audio_formats[1]);
2108
0
  ASSERT_EQ("0",   audio_formats[2]);
2109
0
  ASSERT_EQ("8",   audio_formats[3]);
2110
0
  ASSERT_EQ("101", audio_formats[4]);
2111
0
2112
0
  ASSERT_EQ(SdpMediaSection::kVideo, mSdp->GetMediaSection(1).GetMediaType())
2113
0
    << "Wrong type for second media section";
2114
0
  ASSERT_EQ(SdpMediaSection::kRtpSavpf,
2115
0
            mSdp->GetMediaSection(1).GetProtocol())
2116
0
    << "Wrong protocol for video";
2117
0
  auto video_formats = mSdp->GetMediaSection(1).GetFormats();
2118
0
  ASSERT_EQ(4U, video_formats.size()) << "Wrong number of formats for video";
2119
0
  ASSERT_EQ("120", video_formats[0]);
2120
0
  ASSERT_EQ("121", video_formats[1]);
2121
0
  ASSERT_EQ("122", video_formats[2]);
2122
0
  ASSERT_EQ("123", video_formats[3]);
2123
0
2124
0
  ASSERT_EQ(SdpMediaSection::kAudio, mSdp->GetMediaSection(2).GetMediaType())
2125
0
    << "Wrong type for third media section";
2126
0
}
2127
2128
0
TEST_P(NewSdpTest, CheckSetup) {
2129
0
  ParseSdp(kBasicAudioVideoOffer);
2130
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2131
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
2132
0
2133
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2134
0
      SdpAttribute::kSetupAttribute));
2135
0
  ASSERT_EQ(SdpSetupAttribute::kActpass,
2136
0
      mSdp->GetMediaSection(0).GetAttributeList().GetSetup().mRole);
2137
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2138
0
      SdpAttribute::kSetupAttribute));
2139
0
  ASSERT_EQ(SdpSetupAttribute::kActive,
2140
0
      mSdp->GetMediaSection(1).GetAttributeList().GetSetup().mRole);
2141
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
2142
0
        SdpAttribute::kSetupAttribute));
2143
0
}
2144
2145
TEST_P(NewSdpTest, CheckSsrc)
2146
0
{
2147
0
  ParseSdp(kBasicAudioVideoOffer);
2148
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2149
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
2150
0
2151
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2152
0
      SdpAttribute::kSsrcAttribute));
2153
0
  auto ssrcs = mSdp->GetMediaSection(0).GetAttributeList().GetSsrc().mSsrcs;
2154
0
  ASSERT_EQ(1U, ssrcs.size());
2155
0
  ASSERT_EQ(5150U, ssrcs[0].ssrc);
2156
0
  ASSERT_EQ("", ssrcs[0].attribute);
2157
0
2158
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2159
0
      SdpAttribute::kSsrcAttribute));
2160
0
  ssrcs = mSdp->GetMediaSection(1).GetAttributeList().GetSsrc().mSsrcs;
2161
0
  ASSERT_EQ(3U, ssrcs.size());
2162
0
  ASSERT_EQ(1111U, ssrcs[0].ssrc);
2163
0
  ASSERT_EQ("foo", ssrcs[0].attribute);
2164
0
  ASSERT_EQ(1111U, ssrcs[1].ssrc);
2165
0
  ASSERT_EQ("foo:bar", ssrcs[1].attribute);
2166
0
  ASSERT_EQ(1111U, ssrcs[2].ssrc);
2167
0
  ASSERT_EQ("msid:1d0cdb4e-5934-4f0f-9f88-40392cb60d31 "
2168
0
                 "315b086a-5cb6-4221-89de-caf0b038c79d",
2169
0
            ssrcs[2].attribute);
2170
0
}
2171
2172
0
TEST_P(NewSdpTest, CheckRtpmap) {
2173
0
  ParseSdp(kBasicAudioVideoOffer);
2174
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2175
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
2176
0
    << "Wrong number of media sections";
2177
0
2178
0
  const SdpMediaSection& audiosec = mSdp->GetMediaSection(0);
2179
0
  const SdpRtpmapAttributeList& rtpmap = audiosec.GetAttributeList().GetRtpmap();
2180
0
  ASSERT_EQ(5U, rtpmap.mRtpmaps.size())
2181
0
    << "Wrong number of rtpmap attributes for audio";
2182
0
2183
0
  // Need to know name of type
2184
0
  CheckRtpmap("109",
2185
0
              SdpRtpmapAttributeList::kOpus,
2186
0
              "opus",
2187
0
              48000,
2188
0
              2,
2189
0
              audiosec.GetFormats()[0],
2190
0
              rtpmap);
2191
0
2192
0
  CheckRtpmap("9",
2193
0
              SdpRtpmapAttributeList::kG722,
2194
0
              "G722",
2195
0
              8000,
2196
0
              1,
2197
0
              audiosec.GetFormats()[1],
2198
0
              rtpmap);
2199
0
2200
0
  CheckRtpmap("0",
2201
0
              SdpRtpmapAttributeList::kPCMU,
2202
0
              "PCMU",
2203
0
              8000,
2204
0
              1,
2205
0
              audiosec.GetFormats()[2],
2206
0
              rtpmap);
2207
0
2208
0
  CheckRtpmap("8",
2209
0
              SdpRtpmapAttributeList::kPCMA,
2210
0
              "PCMA",
2211
0
              8000,
2212
0
              1,
2213
0
              audiosec.GetFormats()[3],
2214
0
              rtpmap);
2215
0
2216
0
  CheckRtpmap("101",
2217
0
              SdpRtpmapAttributeList::kTelephoneEvent,
2218
0
              "telephone-event",
2219
0
              8000,
2220
0
              1,
2221
0
              audiosec.GetFormats()[4],
2222
0
              rtpmap);
2223
0
2224
0
  const SdpMediaSection& videosec = mSdp->GetMediaSection(1);
2225
0
  const SdpRtpmapAttributeList videoRtpmap =
2226
0
    videosec.GetAttributeList().GetRtpmap();
2227
0
  ASSERT_EQ(4U, videoRtpmap.mRtpmaps.size())
2228
0
    << "Wrong number of rtpmap attributes for video";
2229
0
2230
0
  CheckRtpmap("120",
2231
0
              SdpRtpmapAttributeList::kVP8,
2232
0
              "VP8",
2233
0
              90000,
2234
0
              0,
2235
0
              videosec.GetFormats()[0],
2236
0
              videoRtpmap);
2237
0
2238
0
  CheckRtpmap("121",
2239
0
              SdpRtpmapAttributeList::kVP9,
2240
0
              "VP9",
2241
0
              90000,
2242
0
              0,
2243
0
              videosec.GetFormats()[1],
2244
0
              videoRtpmap);
2245
0
2246
0
  CheckRtpmap("122",
2247
0
              SdpRtpmapAttributeList::kRed,
2248
0
              "red",
2249
0
              90000,
2250
0
              0,
2251
0
              videosec.GetFormats()[2],
2252
0
              videoRtpmap);
2253
0
2254
0
  CheckRtpmap("123",
2255
0
              SdpRtpmapAttributeList::kUlpfec,
2256
0
              "ulpfec",
2257
0
              90000,
2258
0
              0,
2259
0
              videosec.GetFormats()[3],
2260
0
              videoRtpmap);
2261
0
}
2262
2263
static const std::string kAudioWithTelephoneEvent =
2264
  "v=0" CRLF
2265
  "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
2266
  "s=SIP Call" CRLF
2267
  "c=IN IP4 198.51.100.7" CRLF
2268
  "t=0 0" CRLF
2269
  "m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF
2270
  "c=IN IP4 0.0.0.0" CRLF
2271
  "a=mid:first" CRLF
2272
  "a=rtpmap:109 opus/48000/2" CRLF
2273
  "a=fmtp:109 maxplaybackrate=32000;stereo=1" CRLF
2274
  "a=ptime:20" CRLF
2275
  "a=maxptime:20" CRLF
2276
  "a=rtpmap:9 G722/8000" CRLF
2277
  "a=rtpmap:0 PCMU/8000" CRLF
2278
  "a=rtpmap:8 PCMA/8000" CRLF
2279
  "a=rtpmap:101 telephone-event/8000" CRLF;
2280
2281
0
TEST_P(NewSdpTest, CheckTelephoneEventNoFmtp) {
2282
0
  ParseSdp(kAudioWithTelephoneEvent);
2283
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2284
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2285
0
    << "Wrong number of media sections";
2286
0
2287
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2288
0
              SdpAttribute::kFmtpAttribute));
2289
0
  auto audio_format_params =
2290
0
      mSdp->GetMediaSection(0).GetAttributeList().GetFmtp().mFmtps;
2291
0
  ASSERT_EQ(1U, audio_format_params.size());
2292
0
2293
0
  // make sure we don't get a fmtp for codec 101
2294
0
  for (size_t i = 0; i < audio_format_params.size(); ++i) {
2295
0
    ASSERT_NE("101", audio_format_params[i].format);
2296
0
  }
2297
0
}
2298
2299
0
TEST_P(NewSdpTest, CheckTelephoneEventWithDefaultEvents) {
2300
0
  ParseSdp(kAudioWithTelephoneEvent
2301
0
           + "a=fmtp:101 0-15" CRLF);
2302
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2303
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2304
0
    << "Wrong number of media sections";
2305
0
2306
0
  CheckDtmfFmtp("0-15");
2307
0
}
2308
2309
0
TEST_P(NewSdpTest, CheckTelephoneEventWithBadCharacter) {
2310
0
  ParseSdp(kAudioWithTelephoneEvent
2311
0
           + "a=fmtp:101 0-5." CRLF);
2312
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2313
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2314
0
    << "Wrong number of media sections";
2315
0
2316
0
  CheckDtmfFmtp("0-15");
2317
0
}
2318
2319
0
TEST_P(NewSdpTest, CheckTelephoneEventIncludingCommas) {
2320
0
  ParseSdp(kAudioWithTelephoneEvent
2321
0
           + "a=fmtp:101 0-15,66,67" CRLF);
2322
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2323
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2324
0
    << "Wrong number of media sections";
2325
0
2326
0
  CheckDtmfFmtp("0-15,66,67");
2327
0
}
2328
2329
0
TEST_P(NewSdpTest, CheckTelephoneEventComplexEvents) {
2330
0
  ParseSdp(kAudioWithTelephoneEvent
2331
0
           + "a=fmtp:101 0,1,2-4,5-15,66,67" CRLF);
2332
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2333
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2334
0
    << "Wrong number of media sections";
2335
0
2336
0
  CheckDtmfFmtp("0,1,2-4,5-15,66,67");
2337
0
}
2338
2339
0
TEST_P(NewSdpTest, CheckTelephoneEventNoHyphen) {
2340
0
  ParseSdp(kAudioWithTelephoneEvent
2341
0
           + "a=fmtp:101 5,6,7" CRLF);
2342
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2343
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2344
0
    << "Wrong number of media sections";
2345
0
2346
0
  CheckDtmfFmtp("5,6,7");
2347
0
}
2348
2349
0
TEST_P(NewSdpTest, CheckTelephoneEventOnlyZero) {
2350
0
  ParseSdp(kAudioWithTelephoneEvent
2351
0
           + "a=fmtp:101 0" CRLF);
2352
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2353
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2354
0
    << "Wrong number of media sections";
2355
0
2356
0
  CheckDtmfFmtp("0");
2357
0
}
2358
2359
0
TEST_P(NewSdpTest, CheckTelephoneEventOnlyOne) {
2360
0
  ParseSdp(kAudioWithTelephoneEvent
2361
0
           + "a=fmtp:101 1" CRLF);
2362
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2363
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2364
0
    << "Wrong number of media sections";
2365
0
2366
0
  CheckDtmfFmtp("1");
2367
0
}
2368
2369
0
TEST_P(NewSdpTest, CheckTelephoneEventBadThreeDigit) {
2370
0
  ParseSdp(kAudioWithTelephoneEvent
2371
0
           + "a=fmtp:101 123" CRLF);
2372
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2373
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2374
0
    << "Wrong number of media sections";
2375
0
2376
0
  // check for the default dtmf tones
2377
0
  CheckDtmfFmtp("0-15");
2378
0
}
2379
2380
0
TEST_P(NewSdpTest, CheckTelephoneEventBadThreeDigitWithHyphen) {
2381
0
  ParseSdp(kAudioWithTelephoneEvent
2382
0
           + "a=fmtp:101 0-123" CRLF);
2383
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2384
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2385
0
    << "Wrong number of media sections";
2386
0
2387
0
  // check for the default dtmf tones
2388
0
  CheckDtmfFmtp("0-15");
2389
0
}
2390
2391
0
TEST_P(NewSdpTest, CheckTelephoneEventBadLeadingHyphen) {
2392
0
  ParseSdp(kAudioWithTelephoneEvent
2393
0
           + "a=fmtp:101 -12" CRLF);
2394
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2395
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2396
0
    << "Wrong number of media sections";
2397
0
2398
0
  // check for the default dtmf tones
2399
0
  CheckDtmfFmtp("0-15");
2400
0
}
2401
2402
0
TEST_P(NewSdpTest, CheckTelephoneEventBadTrailingHyphen) {
2403
0
  ParseSdp(kAudioWithTelephoneEvent
2404
0
           + "a=fmtp:101 12-" CRLF, false);
2405
0
}
2406
2407
0
TEST_P(NewSdpTest, CheckTelephoneEventBadTrailingHyphenInMiddle) {
2408
0
  ParseSdp(kAudioWithTelephoneEvent
2409
0
           + "a=fmtp:101 1,12-,4" CRLF, false);
2410
0
}
2411
2412
0
TEST_P(NewSdpTest, CheckTelephoneEventBadLeadingComma) {
2413
0
  ParseSdp(kAudioWithTelephoneEvent
2414
0
           + "a=fmtp:101 ,2,3" CRLF);
2415
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2416
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2417
0
    << "Wrong number of media sections";
2418
0
2419
0
  // check for the default dtmf tones
2420
0
  CheckDtmfFmtp("0-15");
2421
0
}
2422
2423
0
TEST_P(NewSdpTest, CheckTelephoneEventBadMultipleLeadingComma) {
2424
0
  ParseSdp(kAudioWithTelephoneEvent
2425
0
           + "a=fmtp:101 ,,,2,3" CRLF);
2426
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2427
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2428
0
    << "Wrong number of media sections";
2429
0
2430
0
  // check for the default dtmf tones
2431
0
  CheckDtmfFmtp("0-15");
2432
0
}
2433
2434
0
TEST_P(NewSdpTest, CheckTelephoneEventBadConsecutiveCommas) {
2435
0
  ParseSdp(kAudioWithTelephoneEvent
2436
0
           + "a=fmtp:101 1,,,,,,,,3" CRLF);
2437
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2438
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2439
0
    << "Wrong number of media sections";
2440
0
2441
0
  // check for the default dtmf tones
2442
0
  CheckDtmfFmtp("0-15");
2443
0
}
2444
2445
0
TEST_P(NewSdpTest, CheckTelephoneEventBadTrailingComma) {
2446
0
  ParseSdp(kAudioWithTelephoneEvent
2447
0
           + "a=fmtp:101 1,2,3," CRLF);
2448
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2449
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2450
0
    << "Wrong number of media sections";
2451
0
2452
0
  // check for the default dtmf tones
2453
0
  CheckDtmfFmtp("0-15");
2454
0
}
2455
2456
0
TEST_P(NewSdpTest, CheckTelephoneEventBadTwoHyphens) {
2457
0
  ParseSdp(kAudioWithTelephoneEvent
2458
0
           + "a=fmtp:101 1-2-3" CRLF);
2459
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2460
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2461
0
    << "Wrong number of media sections";
2462
0
2463
0
  // check for the default dtmf tones
2464
0
  CheckDtmfFmtp("0-15");
2465
0
}
2466
2467
0
TEST_P(NewSdpTest, CheckTelephoneEventBadSixDigit) {
2468
0
  ParseSdp(kAudioWithTelephoneEvent
2469
0
           + "a=fmtp:101 112233" CRLF);
2470
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2471
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2472
0
    << "Wrong number of media sections";
2473
0
2474
0
  // check for the default dtmf tones
2475
0
  CheckDtmfFmtp("0-15");
2476
0
}
2477
2478
0
TEST_P(NewSdpTest, CheckTelephoneEventBadRangeReversed) {
2479
0
  ParseSdp(kAudioWithTelephoneEvent
2480
0
           + "a=fmtp:101 33-2" CRLF);
2481
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2482
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2483
0
    << "Wrong number of media sections";
2484
0
2485
0
  // check for the default dtmf tones
2486
0
  CheckDtmfFmtp("0-15");
2487
0
}
2488
2489
static const std::string kVideoWithRedAndUlpfecSdp =
2490
  "v=0" CRLF
2491
  "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
2492
  "s=SIP Call" CRLF
2493
  "c=IN IP4 198.51.100.7" CRLF
2494
  "t=0 0" CRLF
2495
  "m=video 9 RTP/SAVPF 97 120 121 122 123" CRLF
2496
  "c=IN IP6 ::1" CRLF
2497
  "a=fingerprint:sha-1 DF:FA:FB:08:3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C" CRLF
2498
  "a=rtpmap:97 H264/90000" CRLF
2499
  "a=fmtp:97 profile-level-id=42a01e" CRLF
2500
  "a=rtpmap:120 VP8/90000" CRLF
2501
  "a=fmtp:120 max-fs=3600;max-fr=30" CRLF
2502
  "a=rtpmap:121 VP9/90000" CRLF
2503
  "a=fmtp:121 max-fs=3600;max-fr=30" CRLF
2504
  "a=rtpmap:122 red/90000" CRLF
2505
  "a=rtpmap:123 ulpfec/90000" CRLF;
2506
2507
0
TEST_P(NewSdpTest, CheckRedNoFmtp) {
2508
0
  ParseSdp(kVideoWithRedAndUlpfecSdp);
2509
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2510
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2511
0
    << "Wrong number of media sections";
2512
0
2513
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2514
0
              SdpAttribute::kFmtpAttribute));
2515
0
  auto video_format_params =
2516
0
      mSdp->GetMediaSection(0).GetAttributeList().GetFmtp().mFmtps;
2517
0
  ASSERT_EQ(3U, video_format_params.size());
2518
0
2519
0
  // make sure we don't get a fmtp for codec 122
2520
0
  for (size_t i = 0; i < video_format_params.size(); ++i) {
2521
0
    ASSERT_NE("122", video_format_params[i].format);
2522
0
  }
2523
0
}
2524
2525
0
TEST_P(NewSdpTest, CheckRedEmptyFmtp) {
2526
0
  // if serializing and re-parsing, we expect errors
2527
0
  if (::testing::get<0>(GetParam())) {
2528
0
    ParseSdp(kVideoWithRedAndUlpfecSdp + "a=fmtp:122" CRLF);
2529
0
  } else {
2530
0
    ParseSdp(kVideoWithRedAndUlpfecSdp + "a=fmtp:122" CRLF, false);
2531
0
2532
0
    if (IsParsingWithSipccParser()) {
2533
0
      ASSERT_NE(0U, GetParseErrors().size());
2534
0
    } else {
2535
0
      // This is the branch for the rust parser to check for warnings, as the
2536
0
      // rust parser will give a warning at that point instead of an error.
2537
0
      ASSERT_NE(0U, GetParseWarnings().size());
2538
0
    }
2539
0
  }
2540
0
2541
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2542
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2543
0
    << "Wrong number of media sections";
2544
0
2545
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2546
0
              SdpAttribute::kFmtpAttribute));
2547
0
  auto video_format_params =
2548
0
      mSdp->GetMediaSection(0).GetAttributeList().GetFmtp().mFmtps;
2549
0
  ASSERT_EQ(3U, video_format_params.size());
2550
0
2551
0
  // make sure we don't get a fmtp for codec 122
2552
0
  for (size_t i = 0; i < video_format_params.size(); ++i) {
2553
0
    ASSERT_NE("122", video_format_params[i].format);
2554
0
  }
2555
0
}
2556
2557
0
TEST_P(NewSdpTest, CheckRedFmtpWith2Codecs) {
2558
0
  ParseSdp(kVideoWithRedAndUlpfecSdp + "a=fmtp:122 120/121" CRLF);
2559
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2560
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2561
0
    << "Wrong number of media sections";
2562
0
2563
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2564
0
              SdpAttribute::kFmtpAttribute));
2565
0
  auto video_format_params =
2566
0
      mSdp->GetMediaSection(0).GetAttributeList().GetFmtp().mFmtps;
2567
0
  ASSERT_EQ(4U, video_format_params.size());
2568
0
2569
0
  ASSERT_EQ("122", video_format_params[3].format);
2570
0
  ASSERT_TRUE(!!video_format_params[3].parameters);
2571
0
  ASSERT_EQ(SdpRtpmapAttributeList::kRed,
2572
0
            video_format_params[3].parameters->codec_type);
2573
0
  const SdpFmtpAttributeList::RedParameters* red_parameters(
2574
0
      static_cast<SdpFmtpAttributeList::RedParameters*>(
2575
0
        video_format_params[3].parameters.get()));
2576
0
  ASSERT_EQ(2U, red_parameters->encodings.size());
2577
0
  ASSERT_EQ(120U, red_parameters->encodings[0]);
2578
0
  ASSERT_EQ(121U, red_parameters->encodings[1]);
2579
0
}
2580
2581
0
TEST_P(NewSdpTest, CheckRedFmtpWith3Codecs) {
2582
0
  ParseSdp(kVideoWithRedAndUlpfecSdp + "a=fmtp:122 120/121/123" CRLF);
2583
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2584
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount())
2585
0
    << "Wrong number of media sections";
2586
0
2587
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2588
0
              SdpAttribute::kFmtpAttribute));
2589
0
  auto video_format_params =
2590
0
      mSdp->GetMediaSection(0).GetAttributeList().GetFmtp().mFmtps;
2591
0
  ASSERT_EQ(4U, video_format_params.size());
2592
0
2593
0
  ASSERT_EQ("122", video_format_params[3].format);
2594
0
  ASSERT_TRUE(!!video_format_params[3].parameters);
2595
0
  ASSERT_EQ(SdpRtpmapAttributeList::kRed,
2596
0
            video_format_params[3].parameters->codec_type);
2597
0
  const SdpFmtpAttributeList::RedParameters* red_parameters(
2598
0
      static_cast<SdpFmtpAttributeList::RedParameters*>(
2599
0
        video_format_params[3].parameters.get()));
2600
0
  ASSERT_EQ(3U, red_parameters->encodings.size());
2601
0
  ASSERT_EQ(120U, red_parameters->encodings[0]);
2602
0
  ASSERT_EQ(121U, red_parameters->encodings[1]);
2603
0
  ASSERT_EQ(123U, red_parameters->encodings[2]);
2604
0
}
2605
2606
const std::string kH264AudioVideoOffer =
2607
"v=0" CRLF
2608
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
2609
"s=SIP Call" CRLF
2610
"c=IN IP4 224.0.0.1/100/12" CRLF
2611
"t=0 0" CRLF
2612
"a=ice-ufrag:4a799b2e" CRLF
2613
"a=ice-pwd:e4cc12a910f106a0a744719425510e17" CRLF
2614
"a=ice-lite" CRLF
2615
"a=msid-semantic:WMS stream streama" CRLF
2616
"a=fingerprint:sha-256 DF:2E:AC:8A:FD:0A:8E:99:BF:5D:E8:3C:E7:FA:FB:08:3B:3C:54:1D:D7:D4:05:77:A0:72:9B:14:08:6D:0F:4C" CRLF
2617
"a=group:BUNDLE first second" CRLF
2618
"a=group:BUNDLE third" CRLF
2619
"a=group:LS first third" CRLF
2620
"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF
2621
"c=IN IP4 0.0.0.0" CRLF
2622
"a=mid:first" CRLF
2623
"a=rtpmap:109 opus/48000/2" CRLF
2624
"a=ptime:20" CRLF
2625
"a=maxptime:20" CRLF
2626
"a=rtpmap:9 G722/8000" CRLF
2627
"a=rtpmap:0 PCMU/8000" CRLF
2628
"a=rtpmap:8 PCMA/8000" CRLF
2629
"a=rtpmap:101 telephone-event/8000" CRLF
2630
"a=fmtp:109 maxplaybackrate=32000;stereo=1;useinbandfec=1" CRLF
2631
"a=fmtp:101 0-15,66,32-34,67" CRLF
2632
"a=ice-ufrag:00000000" CRLF
2633
"a=ice-pwd:0000000000000000000000000000000" CRLF
2634
"a=sendonly" CRLF
2635
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level" CRLF
2636
"a=setup:actpass" CRLF
2637
"a=rtcp-mux" CRLF
2638
"a=msid:stream track" CRLF
2639
"a=candidate:0 1 UDP 2130379007 10.0.0.36 62453 typ host" CRLF
2640
"a=candidate:2 1 UDP 1694236671 24.6.134.204 62453 typ srflx raddr 10.0.0.36 rport 62453" CRLF
2641
"a=candidate:3 1 UDP 100401151 162.222.183.171 49761 typ relay raddr 162.222.183.171 rport 49761" CRLF
2642
"a=candidate:6 1 UDP 16515071 162.222.183.171 51858 typ relay raddr 162.222.183.171 rport 51858" CRLF
2643
"a=candidate:3 2 UDP 100401150 162.222.183.171 62454 typ relay raddr 162.222.183.171 rport 62454" CRLF
2644
"a=candidate:2 2 UDP 1694236670 24.6.134.204 55428 typ srflx raddr 10.0.0.36 rport 55428" CRLF
2645
"a=candidate:6 2 UDP 16515070 162.222.183.171 50340 typ relay raddr 162.222.183.171 rport 50340" CRLF
2646
"a=candidate:0 2 UDP 2130379006 10.0.0.36 55428 typ host" CRLF
2647
"m=video 9 RTP/SAVPF 97 98 120" CRLF
2648
"c=IN IP6 ::1" CRLF
2649
"a=mid:second" CRLF
2650
"a=rtpmap:97 H264/90000" CRLF
2651
"a=fmtp:97 profile-level-id=42a01e" CRLF
2652
"a=rtpmap:98 H264/90000" CRLF
2653
"a=fmtp:98 PROFILE=0;LEVEL=0;parameter-add=1;profile-level-id=42a00d;packetization-mode=1;level-asymmetry-allowed=1;max-mbps=42000;max-fs=1400;max-cpb=1000;max-dpb=1000;max-br=180000;usedtx=0;stereo=0;useinbandfec=0;cbr=0" CRLF
2654
"a=rtpmap:120 VP8/90000" CRLF
2655
"a=fmtp:120 max-fs=3601;max-fr=31" CRLF
2656
"a=recvonly" CRLF
2657
"a=setup:active" CRLF
2658
"a=rtcp-mux" CRLF
2659
"a=msid:streama tracka" CRLF
2660
"a=msid:streamb trackb" CRLF
2661
"a=candidate:0 1 UDP 2130379007 10.0.0.36 59530 typ host" CRLF
2662
"a=candidate:0 2 UDP 2130379006 10.0.0.36 64378 typ host" CRLF
2663
"a=candidate:2 2 UDP 1694236670 24.6.134.204 64378 typ srflx raddr 10.0.0.36 rport 64378" CRLF
2664
"a=candidate:6 2 UDP 16515070 162.222.183.171 64941 typ relay raddr 162.222.183.171 rport 64941" CRLF
2665
"a=candidate:6 1 UDP 16515071 162.222.183.171 64800 typ relay raddr 162.222.183.171 rport 64800" CRLF
2666
"a=candidate:2 1 UDP 1694236671 24.6.134.204 59530 typ srflx raddr 10.0.0.36 rport 59530" CRLF
2667
"a=candidate:3 1 UDP 100401151 162.222.183.171 62935 typ relay raddr 162.222.183.171 rport 62935" CRLF
2668
"a=candidate:3 2 UDP 100401150 162.222.183.171 61026 typ relay raddr 162.222.183.171 rport 61026" CRLF
2669
"m=audio 9 RTP/SAVPF 0" CRLF
2670
"a=mid:third" CRLF
2671
"a=rtpmap:0 PCMU/8000" CRLF
2672
"a=msid:noappdata" CRLF;
2673
2674
0
TEST_P(NewSdpTest, CheckFormatParameters) {
2675
0
  ParseSdp(kH264AudioVideoOffer);
2676
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2677
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
2678
0
    << "Wrong number of media sections";
2679
0
2680
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2681
0
      SdpAttribute::kFmtpAttribute));
2682
0
  auto audio_format_params =
2683
0
      mSdp->GetMediaSection(0).GetAttributeList().GetFmtp().mFmtps;
2684
0
  ASSERT_EQ(2U, audio_format_params.size());
2685
0
  ASSERT_EQ("109", audio_format_params[0].format);
2686
0
  ASSERT_TRUE(!!audio_format_params[0].parameters);
2687
0
  const SdpFmtpAttributeList::OpusParameters* opus_parameters =
2688
0
    static_cast<SdpFmtpAttributeList::OpusParameters*>(
2689
0
        audio_format_params[0].parameters.get());
2690
0
  ASSERT_EQ(32000U, opus_parameters->maxplaybackrate);
2691
0
  ASSERT_EQ(1U, opus_parameters->stereo);
2692
0
  ASSERT_EQ(1U, opus_parameters->useInBandFec);
2693
0
  ASSERT_EQ("101", audio_format_params[1].format);
2694
0
  ASSERT_TRUE(!!audio_format_params[1].parameters);
2695
0
  const SdpFmtpAttributeList::TelephoneEventParameters* te_parameters =
2696
0
    static_cast<SdpFmtpAttributeList::TelephoneEventParameters*>(
2697
0
        audio_format_params[1].parameters.get());
2698
0
  ASSERT_NE(0U, te_parameters->dtmfTones.size());
2699
0
  ASSERT_EQ("0-15,66,32-34,67", te_parameters->dtmfTones);
2700
0
2701
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2702
0
      SdpAttribute::kFmtpAttribute));
2703
0
  auto video_format_params =
2704
0
      mSdp->GetMediaSection(1).GetAttributeList().GetFmtp().mFmtps;
2705
0
  ASSERT_EQ(3U, video_format_params.size());
2706
0
  ASSERT_EQ("97", video_format_params[0].format);
2707
0
  ASSERT_TRUE(!!video_format_params[0].parameters);
2708
0
  ASSERT_EQ(SdpRtpmapAttributeList::kH264,
2709
0
            video_format_params[0].parameters->codec_type);
2710
0
  const SdpFmtpAttributeList::H264Parameters *h264_parameters(
2711
0
      static_cast<SdpFmtpAttributeList::H264Parameters*>(
2712
0
        video_format_params[0].parameters.get()));
2713
0
  ASSERT_EQ((uint32_t)0x42a01e, h264_parameters->profile_level_id);
2714
0
  ASSERT_EQ(0U, h264_parameters->packetization_mode);
2715
0
  ASSERT_FALSE(static_cast<bool>(h264_parameters->level_asymmetry_allowed));
2716
0
  ASSERT_EQ(0U, h264_parameters->max_mbps);
2717
0
  ASSERT_EQ(0U, h264_parameters->max_fs);
2718
0
  ASSERT_EQ(0U, h264_parameters->max_cpb);
2719
0
  ASSERT_EQ(0U, h264_parameters->max_dpb);
2720
0
  ASSERT_EQ(0U, h264_parameters->max_br);
2721
0
2722
0
  ASSERT_EQ("98", video_format_params[1].format);
2723
0
  ASSERT_TRUE(!!video_format_params[1].parameters);
2724
0
  ASSERT_EQ(SdpRtpmapAttributeList::kH264,
2725
0
            video_format_params[1].parameters->codec_type);
2726
0
  h264_parameters =
2727
0
      static_cast<SdpFmtpAttributeList::H264Parameters*>(
2728
0
        video_format_params[1].parameters.get());
2729
0
  ASSERT_EQ((uint32_t)0x42a00d, h264_parameters->profile_level_id);
2730
0
  ASSERT_EQ(1U, h264_parameters->packetization_mode);
2731
0
  ASSERT_TRUE(static_cast<bool>(h264_parameters->level_asymmetry_allowed));
2732
0
  ASSERT_EQ(42000U, h264_parameters->max_mbps);
2733
0
  ASSERT_EQ(1400U, h264_parameters->max_fs);
2734
0
  ASSERT_EQ(1000U, h264_parameters->max_cpb);
2735
0
  ASSERT_EQ(1000U, h264_parameters->max_dpb);
2736
0
  ASSERT_EQ(180000U, h264_parameters->max_br);
2737
0
2738
0
  ASSERT_EQ("120", video_format_params[2].format);
2739
0
  ASSERT_TRUE(!!video_format_params[2].parameters);
2740
0
  ASSERT_EQ(SdpRtpmapAttributeList::kVP8,
2741
0
            video_format_params[2].parameters->codec_type);
2742
0
  const SdpFmtpAttributeList::VP8Parameters *vp8_parameters =
2743
0
      static_cast<SdpFmtpAttributeList::VP8Parameters*>(
2744
0
        video_format_params[2].parameters.get());
2745
0
  ASSERT_EQ(3601U, vp8_parameters->max_fs);
2746
0
  ASSERT_EQ(31U, vp8_parameters->max_fr);
2747
0
2748
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
2749
0
      SdpAttribute::kFmtpAttribute));
2750
0
}
2751
2752
0
TEST_P(NewSdpTest, CheckPtime) {
2753
0
  ParseSdp(kBasicAudioVideoOffer);
2754
0
  ASSERT_EQ(20U, mSdp->GetMediaSection(0).GetAttributeList().GetPtime());
2755
0
  ASSERT_FALSE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2756
0
      SdpAttribute::kPtimeAttribute));
2757
0
}
2758
2759
0
TEST_P(NewSdpTest, CheckFlags) {
2760
0
  ParseSdp(kBasicAudioVideoOffer);
2761
0
  ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
2762
0
      SdpAttribute::kIceLiteAttribute));
2763
0
  ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2764
0
      SdpAttribute::kIceLiteAttribute));
2765
0
  ASSERT_FALSE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2766
0
      SdpAttribute::kIceLiteAttribute));
2767
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
2768
0
      SdpAttribute::kIceLiteAttribute));
2769
0
2770
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2771
0
      SdpAttribute::kRtcpMuxAttribute));
2772
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
2773
0
      SdpAttribute::kRtcpMuxAttribute));
2774
0
2775
0
  ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2776
0
      SdpAttribute::kBundleOnlyAttribute));
2777
0
  ASSERT_TRUE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
2778
0
      SdpAttribute::kBundleOnlyAttribute));
2779
0
2780
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2781
0
      SdpAttribute::kEndOfCandidatesAttribute));
2782
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2783
0
      SdpAttribute::kEndOfCandidatesAttribute));
2784
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
2785
0
      SdpAttribute::kEndOfCandidatesAttribute));
2786
0
}
2787
2788
0
TEST_P(NewSdpTest, CheckConnectionLines) {
2789
0
  ParseSdp(kBasicAudioVideoOffer);
2790
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2791
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
2792
0
    << "Wrong number of media sections";
2793
0
2794
0
  const SdpConnection& conn1 = mSdp->GetMediaSection(0).GetConnection();
2795
0
  ASSERT_EQ(sdp::kIPv4, conn1.GetAddrType());
2796
0
  ASSERT_EQ("0.0.0.0", conn1.GetAddress());
2797
0
  ASSERT_EQ(0U, conn1.GetTtl());
2798
0
  ASSERT_EQ(0U, conn1.GetCount());
2799
0
2800
0
  const SdpConnection& conn2 = mSdp->GetMediaSection(1).GetConnection();
2801
0
  ASSERT_EQ(sdp::kIPv6, conn2.GetAddrType());
2802
0
  ASSERT_EQ("::1", conn2.GetAddress());
2803
0
  ASSERT_EQ(0U, conn2.GetTtl());
2804
0
  ASSERT_EQ(0U, conn2.GetCount());
2805
0
2806
0
  // tests that we can fall through to session level as appropriate
2807
0
  const SdpConnection& conn3 = mSdp->GetMediaSection(2).GetConnection();
2808
0
  ASSERT_EQ(sdp::kIPv4, conn3.GetAddrType());
2809
0
  ASSERT_EQ("224.0.0.1", conn3.GetAddress());
2810
0
  ASSERT_EQ(100U, conn3.GetTtl());
2811
0
  ASSERT_EQ(12U, conn3.GetCount());
2812
0
}
2813
2814
0
TEST_P(NewSdpTest, CheckDirections) {
2815
0
  ParseSdp(kBasicAudioVideoOffer);
2816
0
2817
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2818
0
  ASSERT_EQ(SdpDirectionAttribute::kSendonly,
2819
0
            mSdp->GetMediaSection(0).GetAttributeList().GetDirection());
2820
0
  ASSERT_EQ(SdpDirectionAttribute::kRecvonly,
2821
0
            mSdp->GetMediaSection(1).GetAttributeList().GetDirection());
2822
0
  ASSERT_EQ(SdpDirectionAttribute::kSendrecv,
2823
0
            mSdp->GetMediaSection(2).GetAttributeList().GetDirection());
2824
0
}
2825
2826
0
TEST_P(NewSdpTest, CheckCandidates) {
2827
0
  ParseSdp(kBasicAudioVideoOffer);
2828
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2829
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
2830
0
2831
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2832
0
      SdpAttribute::kCandidateAttribute));
2833
0
  auto audio_candidates =
2834
0
      mSdp->GetMediaSection(0).GetAttributeList().GetCandidate();
2835
0
  ASSERT_EQ(8U, audio_candidates.size());
2836
0
  ASSERT_EQ("0 1 UDP 2130379007 10.0.0.36 62453 typ host", audio_candidates[0]);
2837
0
  ASSERT_EQ("2 1 UDP 1694236671 24.6.134.204 62453 typ srflx raddr 10.0.0.36 rport 62453", audio_candidates[1]);
2838
0
  ASSERT_EQ("3 1 UDP 100401151 162.222.183.171 49761 typ relay raddr 162.222.183.171 rport 49761", audio_candidates[2]);
2839
0
  ASSERT_EQ("6 1 UDP 16515071 162.222.183.171 51858 typ relay raddr 162.222.183.171 rport 51858", audio_candidates[3]);
2840
0
  ASSERT_EQ("3 2 UDP 100401150 162.222.183.171 62454 typ relay raddr 162.222.183.171 rport 62454", audio_candidates[4]);
2841
0
  ASSERT_EQ("2 2 UDP 1694236670 24.6.134.204 55428 typ srflx raddr 10.0.0.36 rport 55428", audio_candidates[5]);
2842
0
  ASSERT_EQ("6 2 UDP 16515070 162.222.183.171 50340 typ relay raddr 162.222.183.171 rport 50340", audio_candidates[6]);
2843
0
  ASSERT_EQ("0 2 UDP 2130379006 10.0.0.36 55428 typ host", audio_candidates[7]);
2844
0
2845
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2846
0
      SdpAttribute::kCandidateAttribute));
2847
0
  auto video_candidates =
2848
0
      mSdp->GetMediaSection(1).GetAttributeList().GetCandidate();
2849
0
  ASSERT_EQ(8U, video_candidates.size());
2850
0
  ASSERT_EQ("0 1 UDP 2130379007 10.0.0.36 59530 typ host", video_candidates[0]);
2851
0
  ASSERT_EQ("0 2 UDP 2130379006 10.0.0.36 64378 typ host", video_candidates[1]);
2852
0
  ASSERT_EQ("2 2 UDP 1694236670 24.6.134.204 64378 typ srflx raddr 10.0.0.36 rport 64378", video_candidates[2]);
2853
0
  ASSERT_EQ("6 2 UDP 16515070 162.222.183.171 64941 typ relay raddr 162.222.183.171 rport 64941", video_candidates[3]);
2854
0
  ASSERT_EQ("6 1 UDP 16515071 162.222.183.171 64800 typ relay raddr 162.222.183.171 rport 64800", video_candidates[4]);
2855
0
  ASSERT_EQ("2 1 UDP 1694236671 24.6.134.204 59530 typ srflx raddr 10.0.0.36 rport 59530", video_candidates[5]);
2856
0
  ASSERT_EQ("3 1 UDP 100401151 162.222.183.171 62935 typ relay raddr 162.222.183.171 rport 62935", video_candidates[6]);
2857
0
  ASSERT_EQ("3 2 UDP 100401150 162.222.183.171 61026 typ relay raddr 162.222.183.171 rport 61026", video_candidates[7]);
2858
0
2859
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
2860
0
      SdpAttribute::kCandidateAttribute));
2861
0
}
2862
2863
0
TEST_P(NewSdpTest, CheckMid) {
2864
0
  ParseSdp(kBasicAudioVideoOffer);
2865
0
  ASSERT_EQ("first", mSdp->GetMediaSection(0).GetAttributeList().GetMid());
2866
0
  ASSERT_EQ("second", mSdp->GetMediaSection(1).GetAttributeList().GetMid());
2867
0
  ASSERT_EQ("third", mSdp->GetMediaSection(2).GetAttributeList().GetMid());
2868
0
}
2869
2870
0
TEST_P(NewSdpTest, CheckMsid) {
2871
0
  ParseSdp(kBasicAudioVideoOffer);
2872
0
  ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
2873
0
      SdpAttribute::kMsidSemanticAttribute));
2874
0
  auto semantics = mSdp->GetAttributeList().GetMsidSemantic().mMsidSemantics;
2875
0
  ASSERT_EQ(2U, semantics.size());
2876
0
  ASSERT_EQ("WMS", semantics[0].semantic);
2877
0
  ASSERT_EQ(2U, semantics[0].msids.size());
2878
0
  ASSERT_EQ("stream", semantics[0].msids[0]);
2879
0
  ASSERT_EQ("streama", semantics[0].msids[1]);
2880
0
  ASSERT_EQ("foo", semantics[1].semantic);
2881
0
  ASSERT_EQ(1U, semantics[1].msids.size());
2882
0
  ASSERT_EQ("stream", semantics[1].msids[0]);
2883
0
2884
0
2885
0
  const SdpMsidAttributeList& msids1 =
2886
0
      mSdp->GetMediaSection(0).GetAttributeList().GetMsid();
2887
0
  ASSERT_EQ(1U, msids1.mMsids.size());
2888
0
  ASSERT_EQ("stream", msids1.mMsids[0].identifier);
2889
0
  ASSERT_EQ("track", msids1.mMsids[0].appdata);
2890
0
  const SdpMsidAttributeList& msids2 =
2891
0
      mSdp->GetMediaSection(1).GetAttributeList().GetMsid();
2892
0
  ASSERT_EQ(2U, msids2.mMsids.size());
2893
0
  ASSERT_EQ("streama", msids2.mMsids[0].identifier);
2894
0
  ASSERT_EQ("tracka", msids2.mMsids[0].appdata);
2895
0
  ASSERT_EQ("streamb", msids2.mMsids[1].identifier);
2896
0
  ASSERT_EQ("trackb", msids2.mMsids[1].appdata);
2897
0
  const SdpMsidAttributeList& msids3 =
2898
0
      mSdp->GetMediaSection(2).GetAttributeList().GetMsid();
2899
0
  ASSERT_EQ(1U, msids3.mMsids.size());
2900
0
  ASSERT_EQ("noappdata", msids3.mMsids[0].identifier);
2901
0
  ASSERT_EQ("", msids3.mMsids[0].appdata);
2902
0
}
2903
2904
0
TEST_P(NewSdpTest, CheckRid) {
2905
0
  ParseSdp(kBasicAudioVideoOffer);
2906
0
  ASSERT_TRUE(!!mSdp);
2907
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
2908
0
2909
0
  ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
2910
0
        SdpAttribute::kRidAttribute));
2911
0
  ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2912
0
        SdpAttribute::kRidAttribute));
2913
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2914
0
        SdpAttribute::kRidAttribute));
2915
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
2916
0
        SdpAttribute::kRidAttribute));
2917
0
2918
0
  const SdpRidAttributeList& rids =
2919
0
    mSdp->GetMediaSection(1).GetAttributeList().GetRid();
2920
0
2921
0
  ASSERT_EQ(2U, rids.mRids.size());
2922
0
2923
0
  ASSERT_EQ("bar", rids.mRids[0].id);
2924
0
  ASSERT_EQ(sdp::kRecv, rids.mRids[0].direction);
2925
0
  ASSERT_EQ(1U, rids.mRids[0].formats.size());
2926
0
  ASSERT_EQ(120U, rids.mRids[0].formats[0]);
2927
0
  ASSERT_EQ(800U, rids.mRids[0].constraints.maxWidth);
2928
0
  ASSERT_EQ(600U, rids.mRids[0].constraints.maxHeight);
2929
0
2930
0
  ASSERT_EQ("bar123", rids.mRids[1].id);
2931
0
  ASSERT_EQ(sdp::kRecv, rids.mRids[1].direction);
2932
0
  ASSERT_EQ(0U, rids.mRids[1].formats.size());
2933
0
  ASSERT_EQ(1920U, rids.mRids[1].constraints.maxWidth);
2934
0
  ASSERT_EQ(1080U, rids.mRids[1].constraints.maxHeight);
2935
0
}
2936
2937
0
TEST_P(NewSdpTest, CheckMediaLevelIceUfrag) {
2938
0
  ParseSdp(kBasicAudioVideoOffer);
2939
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2940
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
2941
0
2942
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2943
0
        SdpAttribute::kIceUfragAttribute, true));
2944
0
  ASSERT_EQ("00000000",
2945
0
            mSdp->GetMediaSection(0).GetAttributeList().GetIceUfrag());
2946
0
2947
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2948
0
        SdpAttribute::kIceUfragAttribute, false));
2949
0
2950
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2951
0
        SdpAttribute::kIceUfragAttribute, true));
2952
0
  ASSERT_EQ("4a799b2e",
2953
0
            mSdp->GetMediaSection(1).GetAttributeList().GetIceUfrag());
2954
0
}
2955
2956
0
TEST_P(NewSdpTest, CheckMediaLevelIcePwd) {
2957
0
  ParseSdp(kBasicAudioVideoOffer);
2958
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
2959
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
2960
0
2961
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
2962
0
        SdpAttribute::kIcePwdAttribute));
2963
0
  ASSERT_EQ("0000000000000000000000000000000",
2964
0
            mSdp->GetMediaSection(0).GetAttributeList().GetIcePwd());
2965
0
2966
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
2967
0
        SdpAttribute::kIcePwdAttribute));
2968
0
  ASSERT_EQ("e4cc12a910f106a0a744719425510e17",
2969
0
            mSdp->GetMediaSection(1).GetAttributeList().GetIcePwd());
2970
0
}
2971
2972
0
TEST_P(NewSdpTest, CheckGroups) {
2973
0
  ParseSdp(kBasicAudioVideoOffer);
2974
0
  const SdpGroupAttributeList& group = mSdp->GetAttributeList().GetGroup();
2975
0
  const SdpGroupAttributeList::Group& group1 = group.mGroups[0];
2976
0
  ASSERT_EQ(SdpGroupAttributeList::kBundle, group1.semantics);
2977
0
  ASSERT_EQ(2U, group1.tags.size());
2978
0
  ASSERT_EQ("first", group1.tags[0]);
2979
0
  ASSERT_EQ("second", group1.tags[1]);
2980
0
2981
0
  const SdpGroupAttributeList::Group& group2 = group.mGroups[1];
2982
0
  ASSERT_EQ(SdpGroupAttributeList::kBundle, group2.semantics);
2983
0
  ASSERT_EQ(1U, group2.tags.size());
2984
0
  ASSERT_EQ("third", group2.tags[0]);
2985
0
2986
0
  const SdpGroupAttributeList::Group& group3 = group.mGroups[2];
2987
0
  ASSERT_EQ(SdpGroupAttributeList::kLs, group3.semantics);
2988
0
  ASSERT_EQ(2U, group3.tags.size());
2989
0
  ASSERT_EQ("first", group3.tags[0]);
2990
0
  ASSERT_EQ("third", group3.tags[1]);
2991
0
}
2992
2993
// SDP from a basic A/V call with data channel FFX/FFX
2994
const std::string kBasicAudioVideoDataOffer =
2995
"v=0" CRLF
2996
"o=Mozilla-SIPUA-35.0a1 27987 0 IN IP4 0.0.0.0" CRLF
2997
"s=SIP Call" CRLF
2998
"t=0 0" CRLF
2999
"a=ice-ufrag:8a39d2ae" CRLF
3000
"a=ice-pwd:601d53aba51a318351b3ecf5ee00048f" CRLF
3001
"a=fingerprint:sha-256 30:FF:8E:2B:AC:9D:ED:70:18:10:67:C8:AE:9E:68:F3:86:53:51:B0:AC:31:B7:BE:6D:CF:A4:2E:D3:6E:B4:28" CRLF
3002
"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF
3003
"c=IN IP4 0.0.0.0" CRLF
3004
"a=rtpmap:109 opus/48000/2" CRLF
3005
"a=ptime:20" CRLF
3006
"a=rtpmap:9 G722/8000" CRLF
3007
"a=rtpmap:0 PCMU/8000" CRLF
3008
"a=rtpmap:8 PCMA/8000" CRLF
3009
"a=rtpmap:101 telephone-event/8000" CRLF
3010
"a=fmtp:101 0-15" CRLF
3011
"a=sendrecv" CRLF
3012
"a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level" CRLF
3013
"a=extmap:2/sendonly some_extension" CRLF
3014
"a=extmap:3 some_other_extension some_params some more params" CRLF
3015
"a=setup:actpass" CRLF
3016
"a=rtcp-mux" CRLF
3017
"m=video 9 RTP/SAVPF 120 126 97" CRLF
3018
"c=IN IP4 0.0.0.0" CRLF
3019
"a=rtpmap:120 VP8/90000" CRLF
3020
"a=rtpmap:126 H264/90000" CRLF
3021
"a=fmtp:126 profile-level-id=42e01f;packetization-mode=1" CRLF
3022
"a=rtpmap:97 H264/90000" CRLF
3023
"a=fmtp:97 profile-level-id=42e01f" CRLF
3024
"a=sendrecv" CRLF
3025
// sipcc barfs on this, despite that it is valid syntax
3026
// Do we care about fixing?
3027
//"a=rtcp-fb:120 ack" CRLF // Should be ignored by sipcc
3028
"a=rtcp-fb:120 ack rpsi" CRLF
3029
"a=rtcp-fb:120 ack app foo" CRLF
3030
"a=rtcp-fb:120 ack foo" CRLF // Should be ignored
3031
"a=rtcp-fb:120 nack" CRLF
3032
"a=rtcp-fb:120 nack sli" CRLF
3033
"a=rtcp-fb:120 nack pli" CRLF
3034
"a=rtcp-fb:120 nack rpsi" CRLF
3035
"a=rtcp-fb:120 nack app foo" CRLF
3036
"a=rtcp-fb:120 nack foo" CRLF // Should be ignored
3037
"a=rtcp-fb:120 ccm fir" CRLF
3038
"a=rtcp-fb:120 ccm tmmbr" CRLF
3039
"a=rtcp-fb:120 ccm tstr" CRLF
3040
"a=rtcp-fb:120 ccm vbcm" CRLF
3041
"a=rtcp-fb:120 ccm foo" CRLF // Should be ignored
3042
"a=rtcp-fb:120 trr-int 10" CRLF
3043
"a=rtcp-fb:120 goog-remb" CRLF
3044
"a=rtcp-fb:120 foo" CRLF // Should be ignored
3045
"a=rtcp-fb:126 nack" CRLF
3046
"a=rtcp-fb:126 nack pli" CRLF
3047
"a=rtcp-fb:126 ccm fir" CRLF
3048
"a=rtcp-fb:97 nack" CRLF
3049
"a=rtcp-fb:97 nack pli" CRLF
3050
"a=rtcp-fb:97 ccm fir" CRLF
3051
"a=rtcp-fb:* ccm tmmbr" CRLF
3052
"a=rtcp-fb:120 transport-cc" CRLF
3053
"a=setup:actpass" CRLF
3054
"a=rtcp-mux" CRLF
3055
"m=application 9 DTLS/SCTP 5000" CRLF
3056
"c=IN IP4 0.0.0.0" CRLF
3057
"a=sctpmap:5000 webrtc-datachannel 16" CRLF
3058
"a=setup:actpass" CRLF;
3059
3060
0
TEST_P(NewSdpTest, BasicAudioVideoDataSdpParse) {
3061
0
  ParseSdp(kBasicAudioVideoDataOffer);
3062
0
  ASSERT_EQ(0U, mSdpErrorHolder->GetParseErrors().size()) <<
3063
0
    "Got parse errors: " << GetParseErrors();
3064
0
}
3065
3066
0
TEST_P(NewSdpTest, CheckApplicationParameters) {
3067
0
  ParseSdp(kBasicAudioVideoDataOffer);
3068
0
  ASSERT_TRUE(!!mSdp);
3069
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
3070
0
  ASSERT_EQ(SdpMediaSection::kAudio, mSdp->GetMediaSection(0).GetMediaType())
3071
0
    << "Wrong type for first media section";
3072
0
  ASSERT_EQ(SdpMediaSection::kVideo, mSdp->GetMediaSection(1).GetMediaType())
3073
0
    << "Wrong type for second media section";
3074
0
  ASSERT_EQ(SdpMediaSection::kApplication, mSdp->GetMediaSection(2).GetMediaType())
3075
0
    << "Wrong type for third media section";
3076
0
3077
0
  ASSERT_EQ(SdpMediaSection::kDtlsSctp,
3078
0
            mSdp->GetMediaSection(2).GetProtocol())
3079
0
    << "Wrong protocol for application";
3080
0
  auto app_formats = mSdp->GetMediaSection(2).GetFormats();
3081
0
  ASSERT_EQ(1U, app_formats.size()) << "Wrong number of formats for audio";
3082
0
  ASSERT_EQ("5000", app_formats[0]);
3083
0
3084
0
  const SdpConnection& conn3 = mSdp->GetMediaSection(2).GetConnection();
3085
0
  ASSERT_EQ(sdp::kIPv4, conn3.GetAddrType());
3086
0
  ASSERT_EQ("0.0.0.0", conn3.GetAddress());
3087
0
  ASSERT_EQ(0U, conn3.GetTtl());
3088
0
  ASSERT_EQ(0U, conn3.GetCount());
3089
0
3090
0
  ASSERT_TRUE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
3091
0
      SdpAttribute::kSetupAttribute));
3092
0
  ASSERT_EQ(SdpSetupAttribute::kActpass,
3093
0
      mSdp->GetMediaSection(2).GetAttributeList().GetSetup().mRole);
3094
0
}
3095
3096
0
TEST_P(NewSdpTest, CheckExtmap) {
3097
0
  ParseSdp(kBasicAudioVideoDataOffer);
3098
0
  ASSERT_TRUE(!!mSdp);
3099
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
3100
0
3101
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3102
0
        SdpAttribute::kExtmapAttribute));
3103
0
3104
0
  auto extmaps =
3105
0
    mSdp->GetMediaSection(0).GetAttributeList().GetExtmap().mExtmaps;
3106
0
  ASSERT_EQ(3U, extmaps.size());
3107
0
3108
0
  ASSERT_EQ(1U, extmaps[0].entry);
3109
0
  ASSERT_FALSE(extmaps[0].direction_specified);
3110
0
  ASSERT_EQ("urn:ietf:params:rtp-hdrext:ssrc-audio-level",
3111
0
      extmaps[0].extensionname);
3112
0
  ASSERT_EQ("",
3113
0
      extmaps[0].extensionattributes);
3114
0
3115
0
  ASSERT_EQ(2U, extmaps[1].entry);
3116
0
  ASSERT_TRUE(extmaps[1].direction_specified);
3117
0
  ASSERT_EQ(SdpDirectionAttribute::kSendonly, extmaps[1].direction);
3118
0
  ASSERT_EQ("some_extension",
3119
0
      extmaps[1].extensionname);
3120
0
  ASSERT_EQ("",
3121
0
      extmaps[1].extensionattributes);
3122
0
3123
0
  ASSERT_EQ(3U, extmaps[2].entry);
3124
0
  ASSERT_FALSE(extmaps[2].direction_specified);
3125
0
  ASSERT_EQ("some_other_extension",
3126
0
      extmaps[2].extensionname);
3127
0
  ASSERT_EQ("some_params some more params",
3128
0
      extmaps[2].extensionattributes);
3129
0
}
3130
3131
0
TEST_P(NewSdpTest, CheckRtcpFb) {
3132
0
  ParseSdp(kBasicAudioVideoDataOffer);
3133
0
  ASSERT_TRUE(!!mSdp);
3134
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
3135
0
3136
0
  auto& video_attrs = mSdp->GetMediaSection(1).GetAttributeList();
3137
0
  ASSERT_TRUE(video_attrs.HasAttribute(SdpAttribute::kRtcpFbAttribute));
3138
0
  auto& rtcpfbs = video_attrs.GetRtcpFb().mFeedbacks;
3139
0
3140
0
  if (IsParsingWithSipccParser()) {
3141
0
    ASSERT_EQ(20U, rtcpfbs.size());
3142
0
  } else {
3143
0
    ASSERT_EQ(21U, rtcpfbs.size());
3144
0
  }
3145
0
3146
0
  CheckRtcpFb(rtcpfbs[0], "120", SdpRtcpFbAttributeList::kAck, "rpsi");
3147
0
  CheckRtcpFb(rtcpfbs[1], "120", SdpRtcpFbAttributeList::kAck, "app", "foo");
3148
0
  CheckRtcpFb(rtcpfbs[2], "120", SdpRtcpFbAttributeList::kNack, "");
3149
0
  CheckRtcpFb(rtcpfbs[3], "120", SdpRtcpFbAttributeList::kNack, "sli");
3150
0
  CheckRtcpFb(rtcpfbs[4], "120", SdpRtcpFbAttributeList::kNack, "pli");
3151
0
  CheckRtcpFb(rtcpfbs[5], "120", SdpRtcpFbAttributeList::kNack, "rpsi");
3152
0
  CheckRtcpFb(rtcpfbs[6], "120", SdpRtcpFbAttributeList::kNack, "app", "foo");
3153
0
  CheckRtcpFb(rtcpfbs[7], "120", SdpRtcpFbAttributeList::kCcm, "fir");
3154
0
  CheckRtcpFb(rtcpfbs[8], "120", SdpRtcpFbAttributeList::kCcm, "tmmbr");
3155
0
  CheckRtcpFb(rtcpfbs[9], "120", SdpRtcpFbAttributeList::kCcm, "tstr");
3156
0
  CheckRtcpFb(rtcpfbs[10], "120", SdpRtcpFbAttributeList::kCcm, "vbcm");
3157
0
  CheckRtcpFb(rtcpfbs[11], "120", SdpRtcpFbAttributeList::kTrrInt, "10");
3158
0
  CheckRtcpFb(rtcpfbs[12], "120", SdpRtcpFbAttributeList::kRemb, "");
3159
0
  CheckRtcpFb(rtcpfbs[13], "126", SdpRtcpFbAttributeList::kNack, "");
3160
0
  CheckRtcpFb(rtcpfbs[14], "126", SdpRtcpFbAttributeList::kNack, "pli");
3161
0
  CheckRtcpFb(rtcpfbs[15], "126", SdpRtcpFbAttributeList::kCcm, "fir");
3162
0
  CheckRtcpFb(rtcpfbs[16], "97",  SdpRtcpFbAttributeList::kNack, "");
3163
0
  CheckRtcpFb(rtcpfbs[17], "97",  SdpRtcpFbAttributeList::kNack, "pli");
3164
0
  CheckRtcpFb(rtcpfbs[18], "97", SdpRtcpFbAttributeList::kCcm, "fir");
3165
0
  CheckRtcpFb(rtcpfbs[19], "*", SdpRtcpFbAttributeList::kCcm, "tmmbr");
3166
0
3167
0
  if (!IsParsingWithSipccParser()) {
3168
0
    CheckRtcpFb(rtcpfbs[20], "120", SdpRtcpFbAttributeList::kTransCC, "");
3169
0
  }
3170
0
}
3171
3172
0
TEST_P(NewSdpTest, CheckRtcp) {
3173
0
  ParseSdp(kBasicAudioVideoOffer);
3174
0
  ASSERT_TRUE(!!mSdp);
3175
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
3176
0
3177
0
  ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3178
0
        SdpAttribute::kRtcpAttribute));
3179
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3180
0
        SdpAttribute::kRtcpAttribute));
3181
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
3182
0
        SdpAttribute::kRtcpAttribute));
3183
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
3184
0
        SdpAttribute::kRtcpAttribute));
3185
0
3186
0
  auto& rtcpAttr_0 = mSdp->GetMediaSection(0).GetAttributeList().GetRtcp();
3187
0
  ASSERT_EQ(62454U, rtcpAttr_0.mPort);
3188
0
  ASSERT_EQ(sdp::kInternet, rtcpAttr_0.mNetType);
3189
0
  ASSERT_EQ(sdp::kIPv4, rtcpAttr_0.mAddrType);
3190
0
  ASSERT_EQ("162.222.183.171", rtcpAttr_0.mAddress);
3191
0
3192
0
  auto& rtcpAttr_1 = mSdp->GetMediaSection(1).GetAttributeList().GetRtcp();
3193
0
  ASSERT_EQ(61026U, rtcpAttr_1.mPort);
3194
0
  ASSERT_EQ("", rtcpAttr_1.mAddress);
3195
0
}
3196
3197
TEST_P(NewSdpTest, CheckImageattr)
3198
0
{
3199
0
  ParseSdp(kBasicAudioVideoOffer);
3200
0
  ASSERT_TRUE(!!mSdp);
3201
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
3202
0
3203
0
  ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3204
0
        SdpAttribute::kImageattrAttribute));
3205
0
  ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3206
0
        SdpAttribute::kImageattrAttribute));
3207
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
3208
0
        SdpAttribute::kImageattrAttribute));
3209
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
3210
0
        SdpAttribute::kImageattrAttribute));
3211
0
3212
0
  const SdpImageattrAttributeList& imageattrs =
3213
0
    mSdp->GetMediaSection(1).GetAttributeList().GetImageattr();
3214
0
3215
0
  ASSERT_EQ(2U, imageattrs.mImageattrs.size());
3216
0
  const SdpImageattrAttributeList::Imageattr& imageattr_0(
3217
0
      imageattrs.mImageattrs[0]);
3218
0
  ASSERT_TRUE(imageattr_0.pt.isSome());
3219
0
  ASSERT_EQ(120U, *imageattr_0.pt);
3220
0
  ASSERT_TRUE(imageattr_0.sendAll);
3221
0
  ASSERT_TRUE(imageattr_0.recvAll);
3222
0
3223
0
  const SdpImageattrAttributeList::Imageattr& imageattr_1(
3224
0
      imageattrs.mImageattrs[1]);
3225
0
  ASSERT_TRUE(imageattr_1.pt.isSome());
3226
0
  ASSERT_EQ(121U, *imageattr_1.pt);
3227
0
  ASSERT_FALSE(imageattr_1.sendAll);
3228
0
  ASSERT_FALSE(imageattr_1.recvAll);
3229
0
  ASSERT_EQ(1U, imageattr_1.sendSets.size());
3230
0
  ASSERT_EQ(1U, imageattr_1.sendSets[0].xRange.discreteValues.size());
3231
0
  ASSERT_EQ(640U, imageattr_1.sendSets[0].xRange.discreteValues.front());
3232
0
  ASSERT_EQ(1U, imageattr_1.sendSets[0].yRange.discreteValues.size());
3233
0
  ASSERT_EQ(480U, imageattr_1.sendSets[0].yRange.discreteValues.front());
3234
0
  ASSERT_EQ(1U, imageattr_1.recvSets.size());
3235
0
  ASSERT_EQ(1U, imageattr_1.recvSets[0].xRange.discreteValues.size());
3236
0
  ASSERT_EQ(640U, imageattr_1.recvSets[0].xRange.discreteValues.front());
3237
0
  ASSERT_EQ(1U, imageattr_1.recvSets[0].yRange.discreteValues.size());
3238
0
  ASSERT_EQ(480U, imageattr_1.recvSets[0].yRange.discreteValues.front());
3239
0
}
3240
3241
0
TEST_P(NewSdpTest, CheckSimulcast) {
3242
0
  ParseSdp(kBasicAudioVideoOffer);
3243
0
  ASSERT_TRUE(!!mSdp);
3244
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount()) << "Wrong number of media sections";
3245
0
3246
0
  ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3247
0
        SdpAttribute::kSimulcastAttribute));
3248
0
  ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3249
0
        SdpAttribute::kSimulcastAttribute));
3250
0
  ASSERT_TRUE(mSdp->GetMediaSection(1).GetAttributeList().HasAttribute(
3251
0
        SdpAttribute::kSimulcastAttribute));
3252
0
  ASSERT_FALSE(mSdp->GetMediaSection(2).GetAttributeList().HasAttribute(
3253
0
        SdpAttribute::kSimulcastAttribute));
3254
0
3255
0
  const SdpSimulcastAttribute& simulcast =
3256
0
    mSdp->GetMediaSection(1).GetAttributeList().GetSimulcast();
3257
0
3258
0
  ASSERT_EQ(2U, simulcast.recvVersions.size());
3259
0
  ASSERT_EQ(0U, simulcast.sendVersions.size());
3260
0
  ASSERT_EQ(1U, simulcast.recvVersions[0].choices.size());
3261
0
  ASSERT_EQ("bar", simulcast.recvVersions[0].choices[0]);
3262
0
  ASSERT_EQ(1U, simulcast.recvVersions[1].choices.size());
3263
0
  ASSERT_EQ("bar123", simulcast.recvVersions[1].choices[0]);
3264
0
  ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid,
3265
0
            simulcast.recvVersions.type);
3266
0
}
3267
3268
0
TEST_P(NewSdpTest, CheckSctpmap) {
3269
0
  ParseSdp(kBasicAudioVideoDataOffer);
3270
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
3271
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
3272
0
    << "Wrong number of media sections";
3273
0
3274
0
  const SdpMediaSection& appsec = mSdp->GetMediaSection(2);
3275
0
  ASSERT_TRUE(
3276
0
      appsec.GetAttributeList().HasAttribute(SdpAttribute::kSctpmapAttribute));
3277
0
  const SdpSctpmapAttributeList& sctpmap =
3278
0
    appsec.GetAttributeList().GetSctpmap();
3279
0
3280
0
  ASSERT_EQ(1U, sctpmap.mSctpmaps.size())
3281
0
    << "Wrong number of sctpmap attributes";
3282
0
  ASSERT_EQ(1U, appsec.GetFormats().size());
3283
0
3284
0
  // Need to know name of type
3285
0
  CheckSctpmap("5000",
3286
0
              "webrtc-datachannel",
3287
0
              16,
3288
0
              appsec.GetFormats()[0],
3289
0
              sctpmap);
3290
0
}
3291
3292
0
TEST_P(NewSdpTest, CheckMaxPtime) {
3293
0
  ParseSdp(kBasicAudioVideoOffer);
3294
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
3295
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
3296
0
    << "Wrong number of media sections";
3297
0
3298
0
  ASSERT_TRUE(mSdp->GetMediaSection(0)
3299
0
                          .GetAttributeList()
3300
0
                          .HasAttribute(SdpAttribute::kMaxptimeAttribute));
3301
0
  ASSERT_EQ(mSdp->GetMediaSection(0).GetAttributeList().GetMaxptime(), 20U);
3302
0
}
3303
3304
const std::string kNewSctpportOfferDraft21 =
3305
"v=0" CRLF
3306
"o=Mozilla-SIPUA-35.0a1 27987 0 IN IP4 0.0.0.0" CRLF
3307
"s=SIP Call" CRLF
3308
"t=0 0" CRLF
3309
"a=ice-ufrag:8a39d2ae" CRLF
3310
"a=ice-pwd:601d53aba51a318351b3ecf5ee00048f" CRLF
3311
"a=fingerprint:sha-256 30:FF:8E:2B:AC:9D:ED:70:18:10:67:C8:AE:9E:68:F3:86:53:51:B0:AC:31:B7:BE:6D:CF:A4:2E:D3:6E:B4:28" CRLF
3312
"m=application 9 UDP/DTLS/SCTP webrtc-datachannel" CRLF
3313
"c=IN IP4 0.0.0.0" CRLF
3314
"a=sctp-port:5000" CRLF
3315
"a=max-message-size:10000" CRLF
3316
"a=setup:actpass" CRLF;
3317
3318
0
TEST_P(NewSdpTest, NewSctpportSdpParse) {
3319
0
  ParseSdp(kNewSctpportOfferDraft21, false);
3320
0
}
3321
3322
INSTANTIATE_TEST_CASE_P(RoundTripSerialize,
3323
                        NewSdpTest,
3324
                        ::testing::Combine(::testing::Bool(),
3325
                                           ::testing::Bool()));
3326
3327
const std::string kCandidateInSessionSDP =
3328
"v=0" CRLF
3329
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3330
"s=SIP Call" CRLF
3331
"c=IN IP4 224.0.0.1/100/12" CRLF
3332
"t=0 0" CRLF
3333
"a=candidate:0 1 UDP 2130379007 10.0.0.36 62453 typ host" CRLF
3334
"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF
3335
"c=IN IP4 0.0.0.0" CRLF
3336
"a=rtpmap:109 opus/48000/2" CRLF;
3337
3338
// This may or may not parse, but if it does, the errant candidate attribute
3339
// should be ignored.
3340
0
TEST_P(NewSdpTest, CheckCandidateInSessionLevel) {
3341
0
  ParseSdp(kCandidateInSessionSDP, false);
3342
0
  if (mSdp) {
3343
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3344
0
          SdpAttribute::kCandidateAttribute));
3345
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3346
0
          SdpAttribute::kCandidateAttribute));
3347
0
  }
3348
0
}
3349
3350
const std::string kBundleOnlyInSessionSDP =
3351
"v=0" CRLF
3352
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3353
"s=SIP Call" CRLF
3354
"c=IN IP4 224.0.0.1/100/12" CRLF
3355
"t=0 0" CRLF
3356
"a=bundle-only" CRLF
3357
"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF
3358
"c=IN IP4 0.0.0.0" CRLF
3359
"a=rtpmap:109 opus/48000/2" CRLF;
3360
3361
// This may or may not parse, but if it does, the errant attribute
3362
// should be ignored.
3363
0
TEST_P(NewSdpTest, CheckBundleOnlyInSessionLevel) {
3364
0
  ParseSdp(kBundleOnlyInSessionSDP, false);
3365
0
  if (mSdp) {
3366
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3367
0
          SdpAttribute::kBundleOnlyAttribute));
3368
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3369
0
          SdpAttribute::kBundleOnlyAttribute));
3370
0
  }
3371
0
}
3372
3373
const std::string kFmtpInSessionSDP =
3374
"v=0" CRLF
3375
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3376
"s=SIP Call" CRLF
3377
"c=IN IP4 224.0.0.1/100/12" CRLF
3378
"t=0 0" CRLF
3379
"a=fmtp:109 0-15" CRLF
3380
"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF
3381
"c=IN IP4 0.0.0.0" CRLF
3382
"a=rtpmap:109 opus/48000/2" CRLF;
3383
3384
// This may or may not parse, but if it does, the errant attribute
3385
// should be ignored.
3386
0
TEST_P(NewSdpTest, CheckFmtpInSessionLevel) {
3387
0
  ParseSdp(kFmtpInSessionSDP, false);
3388
0
  if (mSdp) {
3389
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3390
0
          SdpAttribute::kFmtpAttribute));
3391
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3392
0
          SdpAttribute::kFmtpAttribute));
3393
0
  }
3394
0
}
3395
3396
const std::string kIceMismatchInSessionSDP =
3397
"v=0" CRLF
3398
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3399
"s=SIP Call" CRLF
3400
"c=IN IP4 224.0.0.1/100/12" CRLF
3401
"t=0 0" CRLF
3402
"a=ice-mismatch" CRLF
3403
"m=audio 9 RTP/SAVPF 109 9 0 8 101" CRLF
3404
"c=IN IP4 0.0.0.0" CRLF
3405
"a=rtpmap:109 opus/48000/2" CRLF;
3406
3407
// This may or may not parse, but if it does, the errant attribute
3408
// should be ignored.
3409
0
TEST_P(NewSdpTest, CheckIceMismatchInSessionLevel) {
3410
0
  ParseSdp(kIceMismatchInSessionSDP, false);
3411
0
  if (mSdp) {
3412
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3413
0
          SdpAttribute::kIceMismatchAttribute));
3414
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3415
0
          SdpAttribute::kIceMismatchAttribute));
3416
0
  }
3417
0
}
3418
3419
const std::string kImageattrInSessionSDP =
3420
"v=0" CRLF
3421
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3422
"s=SIP Call" CRLF
3423
"c=IN IP4 224.0.0.1/100/12" CRLF
3424
"t=0 0" CRLF
3425
"a=imageattr:120 send * recv *" CRLF
3426
"m=video 9 RTP/SAVPF 120" CRLF
3427
"c=IN IP4 0.0.0.0" CRLF
3428
"a=rtpmap:120 VP8/90000" CRLF;
3429
3430
// This may or may not parse, but if it does, the errant attribute
3431
// should be ignored.
3432
0
TEST_P(NewSdpTest, CheckImageattrInSessionLevel) {
3433
0
  ParseSdp(kImageattrInSessionSDP, false);
3434
0
  if (mSdp) {
3435
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3436
0
          SdpAttribute::kImageattrAttribute));
3437
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3438
0
          SdpAttribute::kImageattrAttribute));
3439
0
  }
3440
0
}
3441
3442
const std::string kLabelInSessionSDP =
3443
"v=0" CRLF
3444
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3445
"s=SIP Call" CRLF
3446
"c=IN IP4 224.0.0.1/100/12" CRLF
3447
"t=0 0" CRLF
3448
"a=label:foobar" CRLF
3449
"m=video 9 RTP/SAVPF 120" CRLF
3450
"c=IN IP4 0.0.0.0" CRLF
3451
"a=rtpmap:120 VP8/90000" CRLF;
3452
3453
// This may or may not parse, but if it does, the errant attribute
3454
// should be ignored.
3455
0
TEST_P(NewSdpTest, CheckLabelInSessionLevel) {
3456
0
  ParseSdp(kLabelInSessionSDP, false);
3457
0
  if (mSdp) {
3458
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3459
0
          SdpAttribute::kLabelAttribute));
3460
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3461
0
          SdpAttribute::kLabelAttribute));
3462
0
  }
3463
0
}
3464
3465
const std::string kMaxptimeInSessionSDP =
3466
"v=0" CRLF
3467
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3468
"s=SIP Call" CRLF
3469
"c=IN IP4 224.0.0.1/100/12" CRLF
3470
"t=0 0" CRLF
3471
"a=maxptime:100" CRLF
3472
"m=video 9 RTP/SAVPF 120" CRLF
3473
"c=IN IP4 0.0.0.0" CRLF
3474
"a=rtpmap:120 VP8/90000" CRLF;
3475
3476
// This may or may not parse, but if it does, the errant attribute
3477
// should be ignored.
3478
0
TEST_P(NewSdpTest, CheckMaxptimeInSessionLevel) {
3479
0
  ParseSdp(kMaxptimeInSessionSDP, false);
3480
0
  if (mSdp) {
3481
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3482
0
          SdpAttribute::kMaxptimeAttribute));
3483
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3484
0
          SdpAttribute::kMaxptimeAttribute));
3485
0
  }
3486
0
}
3487
3488
const std::string kMidInSessionSDP =
3489
"v=0" CRLF
3490
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3491
"s=SIP Call" CRLF
3492
"c=IN IP4 224.0.0.1/100/12" CRLF
3493
"t=0 0" CRLF
3494
"a=mid:foobar" CRLF
3495
"m=video 9 RTP/SAVPF 120" CRLF
3496
"c=IN IP4 0.0.0.0" CRLF
3497
"a=rtpmap:120 VP8/90000" CRLF;
3498
3499
// This may or may not parse, but if it does, the errant attribute
3500
// should be ignored.
3501
0
TEST_P(NewSdpTest, CheckMidInSessionLevel) {
3502
0
  ParseSdp(kMidInSessionSDP, false);
3503
0
  if (mSdp) {
3504
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3505
0
          SdpAttribute::kMidAttribute));
3506
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3507
0
          SdpAttribute::kMidAttribute));
3508
0
  }
3509
0
}
3510
3511
const std::string kMsidInSessionSDP =
3512
"v=0" CRLF
3513
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3514
"s=SIP Call" CRLF
3515
"c=IN IP4 224.0.0.1/100/12" CRLF
3516
"t=0 0" CRLF
3517
"a=msid:foobar" CRLF
3518
"m=video 9 RTP/SAVPF 120" CRLF
3519
"c=IN IP4 0.0.0.0" CRLF
3520
"a=rtpmap:120 VP8/90000" CRLF;
3521
3522
// This may or may not parse, but if it does, the errant attribute
3523
// should be ignored.
3524
0
TEST_P(NewSdpTest, CheckMsidInSessionLevel) {
3525
0
  ParseSdp(kMsidInSessionSDP, false);
3526
0
  if (mSdp) {
3527
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3528
0
          SdpAttribute::kMsidAttribute));
3529
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3530
0
          SdpAttribute::kMsidAttribute));
3531
0
  }
3532
0
}
3533
3534
const std::string kPtimeInSessionSDP =
3535
"v=0" CRLF
3536
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3537
"s=SIP Call" CRLF
3538
"c=IN IP4 224.0.0.1/100/12" CRLF
3539
"t=0 0" CRLF
3540
"a=ptime:50" CRLF
3541
"m=video 9 RTP/SAVPF 120" CRLF
3542
"c=IN IP4 0.0.0.0" CRLF
3543
"a=rtpmap:120 VP8/90000" CRLF;
3544
3545
// This may or may not parse, but if it does, the errant attribute
3546
// should be ignored.
3547
0
TEST_P(NewSdpTest, CheckPtimeInSessionLevel) {
3548
0
  ParseSdp(kPtimeInSessionSDP, false);
3549
0
  if (mSdp) {
3550
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3551
0
          SdpAttribute::kPtimeAttribute));
3552
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3553
0
          SdpAttribute::kPtimeAttribute));
3554
0
  }
3555
0
}
3556
3557
const std::string kRemoteCandidatesInSessionSDP =
3558
"v=0" CRLF
3559
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3560
"s=SIP Call" CRLF
3561
"c=IN IP4 224.0.0.1/100/12" CRLF
3562
"t=0 0" CRLF
3563
"a=remote-candidates:0 10.0.0.1 5555" CRLF
3564
"m=video 9 RTP/SAVPF 120" CRLF
3565
"c=IN IP4 0.0.0.0" CRLF
3566
"a=rtpmap:120 VP8/90000" CRLF;
3567
3568
// This may or may not parse, but if it does, the errant attribute
3569
// should be ignored.
3570
0
TEST_P(NewSdpTest, CheckRemoteCandidatesInSessionLevel) {
3571
0
  ParseSdp(kRemoteCandidatesInSessionSDP, false);
3572
0
  if (mSdp) {
3573
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3574
0
          SdpAttribute::kRemoteCandidatesAttribute));
3575
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3576
0
          SdpAttribute::kRemoteCandidatesAttribute));
3577
0
  }
3578
0
}
3579
3580
const std::string kRtcpInSessionSDP =
3581
"v=0" CRLF
3582
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3583
"s=SIP Call" CRLF
3584
"c=IN IP4 224.0.0.1/100/12" CRLF
3585
"t=0 0" CRLF
3586
"a=rtcp:5555" CRLF
3587
"m=video 9 RTP/SAVPF 120" CRLF
3588
"c=IN IP4 0.0.0.0" CRLF
3589
"a=rtpmap:120 VP8/90000" CRLF;
3590
3591
// This may or may not parse, but if it does, the errant attribute
3592
// should be ignored.
3593
0
TEST_P(NewSdpTest, CheckRtcpInSessionLevel) {
3594
0
  ParseSdp(kRtcpInSessionSDP, false);
3595
0
  if (mSdp) {
3596
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3597
0
          SdpAttribute::kRtcpAttribute));
3598
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3599
0
          SdpAttribute::kRtcpAttribute));
3600
0
  }
3601
0
}
3602
3603
const std::string kRtcpFbInSessionSDP =
3604
"v=0" CRLF
3605
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3606
"s=SIP Call" CRLF
3607
"c=IN IP4 224.0.0.1/100/12" CRLF
3608
"t=0 0" CRLF
3609
"a=rtcp-fb:120 nack" CRLF
3610
"m=video 9 RTP/SAVPF 120" CRLF
3611
"c=IN IP4 0.0.0.0" CRLF
3612
"a=rtpmap:120 VP8/90000" CRLF;
3613
3614
// This may or may not parse, but if it does, the errant attribute
3615
// should be ignored.
3616
0
TEST_P(NewSdpTest, CheckRtcpFbInSessionLevel) {
3617
0
  ParseSdp(kRtcpFbInSessionSDP, false);
3618
0
  if (mSdp) {
3619
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3620
0
          SdpAttribute::kRtcpFbAttribute));
3621
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3622
0
          SdpAttribute::kRtcpFbAttribute));
3623
0
  }
3624
0
}
3625
3626
const std::string kRtcpMuxInSessionSDP =
3627
"v=0" CRLF
3628
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3629
"s=SIP Call" CRLF
3630
"c=IN IP4 224.0.0.1/100/12" CRLF
3631
"t=0 0" CRLF
3632
"a=rtcp-mux" CRLF
3633
"m=video 9 RTP/SAVPF 120" CRLF
3634
"c=IN IP4 0.0.0.0" CRLF
3635
"a=rtpmap:120 VP8/90000" CRLF;
3636
3637
// This may or may not parse, but if it does, the errant attribute
3638
// should be ignored.
3639
0
TEST_P(NewSdpTest, CheckRtcpMuxInSessionLevel) {
3640
0
  ParseSdp(kRtcpMuxInSessionSDP, false);
3641
0
  if (mSdp) {
3642
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3643
0
          SdpAttribute::kRtcpMuxAttribute));
3644
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3645
0
          SdpAttribute::kRtcpMuxAttribute));
3646
0
  }
3647
0
}
3648
3649
const std::string kRtcpRsizeInSessionSDP =
3650
"v=0" CRLF
3651
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3652
"s=SIP Call" CRLF
3653
"c=IN IP4 224.0.0.1/100/12" CRLF
3654
"t=0 0" CRLF
3655
"a=rtcp-rsize" CRLF
3656
"m=video 9 RTP/SAVPF 120" CRLF
3657
"c=IN IP4 0.0.0.0" CRLF
3658
"a=rtpmap:120 VP8/90000" CRLF;
3659
3660
// This may or may not parse, but if it does, the errant attribute
3661
// should be ignored.
3662
0
TEST_P(NewSdpTest, CheckRtcpRsizeInSessionLevel) {
3663
0
  ParseSdp(kRtcpRsizeInSessionSDP, false);
3664
0
  if (mSdp) {
3665
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3666
0
          SdpAttribute::kRtcpRsizeAttribute));
3667
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3668
0
          SdpAttribute::kRtcpRsizeAttribute));
3669
0
  }
3670
0
}
3671
3672
const std::string kRtpmapInSessionSDP =
3673
"v=0" CRLF
3674
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3675
"s=SIP Call" CRLF
3676
"c=IN IP4 224.0.0.1/100/12" CRLF
3677
"t=0 0" CRLF
3678
"a=rtpmap:120 VP8/90000" CRLF
3679
"m=video 9 RTP/SAVPF 120" CRLF
3680
"c=IN IP4 0.0.0.0" CRLF;
3681
3682
// This may or may not parse, but if it does, the errant attribute
3683
// should be ignored.
3684
0
TEST_P(NewSdpTest, CheckRtpmapInSessionLevel) {
3685
0
  ParseSdp(kRtpmapInSessionSDP, false);
3686
0
  if (mSdp) {
3687
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3688
0
          SdpAttribute::kRtpmapAttribute));
3689
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3690
0
          SdpAttribute::kRtpmapAttribute));
3691
0
  }
3692
0
}
3693
3694
const std::string kSctpmapInSessionSDP =
3695
"v=0" CRLF
3696
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3697
"s=SIP Call" CRLF
3698
"c=IN IP4 224.0.0.1/100/12" CRLF
3699
"t=0 0" CRLF
3700
"a=sctpmap:5000" CRLF
3701
"m=video 9 RTP/SAVPF 120" CRLF
3702
"c=IN IP4 0.0.0.0" CRLF
3703
"a=rtpmap:120 VP8/90000" CRLF;
3704
3705
// This may or may not parse, but if it does, the errant attribute
3706
// should be ignored.
3707
0
TEST_P(NewSdpTest, CheckSctpmapInSessionLevel) {
3708
0
  ParseSdp(kSctpmapInSessionSDP, false);
3709
0
  if (mSdp) {
3710
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3711
0
          SdpAttribute::kSctpmapAttribute));
3712
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3713
0
          SdpAttribute::kSctpmapAttribute));
3714
0
  }
3715
0
}
3716
3717
const std::string kSsrcInSessionSDP =
3718
"v=0" CRLF
3719
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3720
"s=SIP Call" CRLF
3721
"c=IN IP4 224.0.0.1/100/12" CRLF
3722
"t=0 0" CRLF
3723
"a=ssrc:5000" CRLF
3724
"m=video 9 RTP/SAVPF 120" CRLF
3725
"c=IN IP4 0.0.0.0" CRLF
3726
"a=rtpmap:120 VP8/90000" CRLF;
3727
3728
// This may or may not parse, but if it does, the errant attribute
3729
// should be ignored.
3730
0
TEST_P(NewSdpTest, CheckSsrcInSessionLevel) {
3731
0
  ParseSdp(kSsrcInSessionSDP, false);
3732
0
  if (mSdp) {
3733
0
    ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3734
0
          SdpAttribute::kSsrcAttribute));
3735
0
    ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3736
0
          SdpAttribute::kSsrcAttribute));
3737
0
  }
3738
0
}
3739
3740
const std::string kMalformedImageattr =
3741
"v=0" CRLF
3742
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3743
"s=SIP Call" CRLF
3744
"c=IN IP4 224.0.0.1/100/12" CRLF
3745
"t=0 0" CRLF
3746
"m=video 9 RTP/SAVPF 120" CRLF
3747
"c=IN IP4 0.0.0.0" CRLF
3748
"a=rtpmap:120 VP8/90000" CRLF
3749
"a=imageattr:flob" CRLF;
3750
3751
TEST_P(NewSdpTest, CheckMalformedImageattr)
3752
0
{
3753
0
  if (::testing::get<0>(GetParam())) {
3754
0
    // Don't do a parse/serialize before running this test
3755
0
    return;
3756
0
  }
3757
0
3758
0
  ParseSdp(kMalformedImageattr, false);
3759
0
  ASSERT_NE("", GetParseErrors());
3760
0
}
3761
3762
0
TEST_P(NewSdpTest, ParseInvalidSimulcastNoSuchSendRid) {
3763
0
  ParseSdp("v=0" CRLF
3764
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
3765
0
           "s=SIP Call" CRLF
3766
0
           "c=IN IP4 198.51.100.7" CRLF
3767
0
           "b=CT:5000" CRLF
3768
0
           "t=0 0" CRLF
3769
0
           "m=video 56436 RTP/SAVPF 120" CRLF
3770
0
           "a=rtpmap:120 VP8/90000" CRLF
3771
0
           "a=sendrecv" CRLF
3772
0
           "a=simulcast: send rid=9" CRLF
3773
0
           "a=rid:9 recv max-width=800;max-height=600" CRLF,
3774
0
           false);
3775
0
  ASSERT_NE("", GetParseErrors());
3776
0
}
3777
3778
0
TEST_P(NewSdpTest, ParseInvalidSimulcastNoSuchRecvRid) {
3779
0
  ParseSdp("v=0" CRLF
3780
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
3781
0
           "s=SIP Call" CRLF
3782
0
           "c=IN IP4 198.51.100.7" CRLF
3783
0
           "b=CT:5000" CRLF
3784
0
           "t=0 0" CRLF
3785
0
           "m=video 56436 RTP/SAVPF 120" CRLF
3786
0
           "a=rtpmap:120 VP8/90000" CRLF
3787
0
           "a=sendrecv" CRLF
3788
0
           "a=simulcast: recv rid=9" CRLF
3789
0
           "a=rid:9 send max-width=800;max-height=600" CRLF,
3790
0
           false);
3791
0
  ASSERT_NE("", GetParseErrors());
3792
0
}
3793
3794
0
TEST_P(NewSdpTest, ParseInvalidSimulcastNotSending) {
3795
0
  ParseSdp("v=0" CRLF
3796
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
3797
0
           "s=SIP Call" CRLF
3798
0
           "c=IN IP4 198.51.100.7" CRLF
3799
0
           "b=CT:5000" CRLF
3800
0
           "t=0 0" CRLF
3801
0
           "m=video 56436 RTP/SAVPF 120" CRLF
3802
0
           "a=rtpmap:120 VP8/90000" CRLF
3803
0
           "a=recvonly" CRLF
3804
0
           "a=simulcast: send rid=120" CRLF,
3805
0
           false);
3806
0
  ASSERT_NE("", GetParseErrors());
3807
0
}
3808
3809
0
TEST_P(NewSdpTest, ParseInvalidSimulcastNotReceiving) {
3810
0
  ParseSdp("v=0" CRLF
3811
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
3812
0
           "s=SIP Call" CRLF
3813
0
           "c=IN IP4 198.51.100.7" CRLF
3814
0
           "b=CT:5000" CRLF
3815
0
           "t=0 0" CRLF
3816
0
           "m=video 56436 RTP/SAVPF 120" CRLF
3817
0
           "a=rtpmap:120 VP8/90000" CRLF
3818
0
           "a=sendonly" CRLF
3819
0
           "a=simulcast: recv rid=120" CRLF,
3820
0
           false);
3821
0
  ASSERT_NE("", GetParseErrors());
3822
0
}
3823
3824
0
TEST_P(NewSdpTest, ParseInvalidRidNoSuchPt) {
3825
0
  SKIP_TEST_WITH_SIPCC_PARSER
3826
0
  ParseSdp("v=0" CRLF
3827
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
3828
0
           "s=SIP Call" CRLF
3829
0
           "c=IN IP4 198.51.100.7" CRLF
3830
0
           "b=CT:5000" CRLF
3831
0
           "t=0 0" CRLF
3832
0
           "m=video 56436 RTP/SAVPF 120" CRLF
3833
0
           "a=rtpmap:120 VP8/90000" CRLF
3834
0
           "a=sendrecv" CRLF
3835
0
           "a=simulcast: recv rid=9" CRLF
3836
0
           "a=rid:9 recv pt=101;max-width=800;max-height=600" CRLF,
3837
0
           false);
3838
0
  ASSERT_NE("", GetParseErrors());
3839
0
}
3840
3841
const std::string kNoAttributes =
3842
"v=0" CRLF
3843
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3844
"s=SIP Call" CRLF
3845
"c=IN IP4 224.0.0.1/100/12" CRLF
3846
"t=0 0" CRLF
3847
"m=video 9 RTP/SAVPF 120" CRLF
3848
"c=IN IP4 0.0.0.0" CRLF
3849
"a=rtpmap:120 VP8/90000" CRLF;
3850
3851
0
TEST_P(NewSdpTest, CheckNoAttributes) {
3852
0
  ParseSdp(kNoAttributes);
3853
0
3854
0
  for (auto a = static_cast<size_t>(SdpAttribute::kFirstAttribute);
3855
0
       a <= static_cast<size_t>(SdpAttribute::kLastAttribute);
3856
0
       ++a) {
3857
0
3858
0
    SdpAttribute::AttributeType type =
3859
0
      static_cast<SdpAttribute::AttributeType>(a);
3860
0
3861
0
    // rtpmap is a special case right now, we throw parse errors if it is
3862
0
    // missing, and then insert one.
3863
0
    // direction is another special case that gets a default if not present
3864
0
    if (type != SdpAttribute::kRtpmapAttribute &&
3865
0
        type != SdpAttribute::kDirectionAttribute) {
3866
0
      ASSERT_FALSE(
3867
0
          mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(type))
3868
0
        << "Attribute " << a << " should not have been present at media level";
3869
0
      ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(type))
3870
0
        << "Attribute " << a << " should not have been present at session level";
3871
0
    }
3872
0
  }
3873
0
3874
0
  ASSERT_FALSE(mSdp->GetAttributeList().HasAttribute(
3875
0
        SdpAttribute::kRtpmapAttribute));
3876
0
3877
0
  ASSERT_TRUE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3878
0
        SdpAttribute::kDirectionAttribute));
3879
0
  ASSERT_EQ(SdpDirectionAttribute::kSendrecv,
3880
0
      mSdp->GetMediaSection(0).GetAttributeList().GetDirection());
3881
0
  ASSERT_TRUE(mSdp->GetAttributeList().HasAttribute(
3882
0
        SdpAttribute::kDirectionAttribute));
3883
0
  ASSERT_EQ(SdpDirectionAttribute::kSendrecv,
3884
0
      mSdp->GetAttributeList().GetDirection());
3885
0
}
3886
3887
3888
const std::string kMediaLevelDtlsMessage =
3889
"v=0" CRLF
3890
"o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
3891
"s=SIP Call" CRLF
3892
"c=IN IP4 224.0.0.1/100/12" CRLF
3893
"t=0 0" CRLF
3894
"m=video 9 RTP/SAVPF 120" CRLF
3895
"c=IN IP4 0.0.0.0" CRLF
3896
"a=dtls-message:client " BASE64_DTLS_HELLO CRLF
3897
"a=rtpmap:120 VP8/90000" CRLF;
3898
3899
0
TEST_P(NewSdpTest, CheckMediaLevelDtlsMessage) {
3900
0
  ParseSdp(kMediaLevelDtlsMessage);
3901
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
3902
0
3903
0
  // dtls-message is not defined for use at the media level; we don't
3904
0
  // parse it
3905
0
  ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().HasAttribute(
3906
0
        SdpAttribute::kDtlsMessageAttribute));
3907
0
}
3908
3909
0
TEST_P(NewSdpTest, CheckSetPort) {
3910
0
  // Parse any valid sdp with a media section
3911
0
  ParseSdp("v=0" CRLF
3912
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
3913
0
           "s=SIP Call" CRLF
3914
0
           "c=IN IP4 198.51.100.7" CRLF
3915
0
           "b=CT:5000" CRLF
3916
0
           "t=0 0" CRLF
3917
0
           "m=video 56436 RTP/SAVPF 120" CRLF
3918
0
           "a=rtpmap:120 VP8/90000" CRLF
3919
0
           "a=sendonly" CRLF,
3920
0
           false);
3921
0
3922
0
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
3923
0
3924
0
   constexpr unsigned int expectedParesPort = 56436;
3925
0
   unsigned int currentPort = mSdp->GetMediaSection(0).GetPort();
3926
0
   ASSERT_EQ(expectedParesPort, currentPort);
3927
0
3928
0
   mSdp->GetMediaSection(0).SetPort(currentPort+1);
3929
0
   ASSERT_EQ(currentPort+1,mSdp->GetMediaSection(0).GetPort());
3930
0
}
3931
3932
0
TEST_P(NewSdpTest, CheckAddCodec) {
3933
0
  // Parse any valid sdp with a media section
3934
0
  ParseSdp("v=0" CRLF
3935
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
3936
0
           "s=SIP Call" CRLF
3937
0
           "c=IN IP4 198.51.100.7" CRLF
3938
0
           "b=CT:5000" CRLF
3939
0
           "t=0 0" CRLF
3940
0
           "m=video 56436 RTP/SAVPF 120" CRLF
3941
0
           "a=rtpmap:120 VP8/90000" CRLF
3942
0
           "a=sendonly" CRLF);
3943
0
3944
0
   ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
3945
0
   ASSERT_EQ(1U,mSdp->GetMediaSectionCount());
3946
0
3947
0
   ASSERT_EQ(1U,mSdp->GetMediaSection(0).GetFormats().size());
3948
0
   ASSERT_EQ(1U,mSdp->GetMediaSection(0).GetAttributeList().GetRtpmap().mRtpmaps.size());
3949
0
3950
0
   mSdp->GetMediaSection(0).AddCodec("110","opus",48000,2);
3951
0
3952
0
   ASSERT_EQ(2U,mSdp->GetMediaSection(0).GetFormats().size());
3953
0
   const auto& rtpmaps = mSdp->GetMediaSection(0).GetAttributeList().GetRtpmap();
3954
0
   ASSERT_EQ(2U,rtpmaps.mRtpmaps.size());
3955
0
3956
0
   ASSERT_TRUE(rtpmaps.HasEntry("120"));
3957
0
   ASSERT_TRUE(rtpmaps.HasEntry("110"));
3958
0
   const auto aRtpmap = rtpmaps.GetEntry("110");
3959
0
   ASSERT_EQ(aRtpmap.pt,"110");
3960
0
   ASSERT_EQ(aRtpmap.codec,SdpRtpmapAttributeList::kOpus);
3961
0
   ASSERT_EQ(aRtpmap.name,"opus");
3962
0
   ASSERT_EQ(aRtpmap.clock,48000U);
3963
0
   ASSERT_EQ(aRtpmap.channels,2U);
3964
0
}
3965
3966
0
TEST_P(NewSdpTest, CheckClearCodecs) {
3967
0
  // Parse any valid sdp with a media section
3968
0
  ParseSdp("v=0" CRLF
3969
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
3970
0
           "s=SIP Call" CRLF
3971
0
           "c=IN IP4 198.51.100.7" CRLF
3972
0
           "b=CT:5000" CRLF
3973
0
           "t=0 0" CRLF
3974
0
           "m=video 56436 RTP/SAVPF 120 110" CRLF
3975
0
           "a=rtpmap:120 VP8/90000" CRLF
3976
0
           "a=sendonly" CRLF
3977
0
           "a=rtpmap:110 opus/48000/2" CRLF);
3978
0
3979
0
     ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
3980
0
     ASSERT_EQ(1U,mSdp->GetMediaSectionCount());
3981
0
3982
0
     ASSERT_EQ(2U,mSdp->GetMediaSection(0).GetFormats().size());
3983
0
     ASSERT_EQ(2U,mSdp->GetMediaSection(0).GetAttributeList().
3984
0
                  GetRtpmap().mRtpmaps.size());
3985
0
3986
0
     mSdp->GetMediaSection(0).ClearCodecs();
3987
0
3988
0
     ASSERT_EQ(0U,mSdp->GetMediaSection(0).GetFormats().size());
3989
0
     ASSERT_FALSE(mSdp->GetMediaSection(0).GetAttributeList().
3990
0
                  HasAttribute(SdpAttribute::kRtpmapAttribute));
3991
0
}
3992
3993
0
TEST_P(NewSdpTest, CheckAddMediaSection) {
3994
0
  ParseSdp(kBasicAudioVideoOffer);
3995
0
3996
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
3997
0
  ASSERT_EQ(3U, mSdp->GetMediaSectionCount())
3998
0
    << "Wrong number of media sections";
3999
0
4000
0
  mSdp->AddMediaSection(SdpMediaSection::kVideo,
4001
0
                        SdpDirectionAttribute::Direction::kSendrecv,
4002
0
                        58000, SdpMediaSection::kUdpDtlsSctp,sdp::kIPv4,
4003
0
                        "127.0.0.1");
4004
0
4005
0
  ASSERT_EQ(4U, mSdp->GetMediaSectionCount())
4006
0
    << "Wrong number of media sections after adding media section";
4007
0
4008
0
  const SdpMediaSection& newMediaSection = mSdp->GetMediaSection(3);
4009
0
4010
0
  ASSERT_EQ(SdpMediaSection::kVideo, newMediaSection.GetMediaType());
4011
0
  ASSERT_EQ(SdpDirectionAttribute::Direction::kSendrecv,
4012
0
            newMediaSection.GetDirectionAttribute().mValue);
4013
0
  ASSERT_EQ(58000U, newMediaSection.GetPort());
4014
0
  ASSERT_EQ(SdpMediaSection::kUdpDtlsSctp, newMediaSection.GetProtocol());
4015
0
  ASSERT_EQ(sdp::kIPv4, newMediaSection.GetConnection().GetAddrType());
4016
0
  ASSERT_EQ("127.0.0.1", newMediaSection.GetConnection().GetAddress());
4017
0
4018
0
4019
0
  mSdp->AddMediaSection(SdpMediaSection::kAudio,
4020
0
                        SdpDirectionAttribute::Direction::kSendonly,
4021
0
                        14006, SdpMediaSection::kTcpTlsRtpSavpf, sdp::kIPv6,
4022
0
                        "2607:f8b0:4004:801::2013");
4023
0
4024
0
  ASSERT_EQ(5U, mSdp->GetMediaSectionCount())
4025
0
    << "Wrong number of media sections after adding media section";
4026
0
4027
0
  const SdpMediaSection& nextNewMediaSection = mSdp->GetMediaSection(4);
4028
0
4029
0
  ASSERT_EQ(SdpMediaSection::kAudio, nextNewMediaSection.GetMediaType());
4030
0
  ASSERT_EQ(SdpDirectionAttribute::Direction::kSendonly,
4031
0
            nextNewMediaSection.GetDirectionAttribute().mValue);
4032
0
  ASSERT_EQ(14006U, nextNewMediaSection.GetPort());
4033
0
  ASSERT_EQ(SdpMediaSection::kTcpTlsRtpSavpf,
4034
0
            nextNewMediaSection.GetProtocol());
4035
0
  ASSERT_EQ(sdp::kIPv6, nextNewMediaSection.GetConnection().GetAddrType());
4036
0
  ASSERT_EQ("2607:f8b0:4004:801::2013",
4037
0
            nextNewMediaSection.GetConnection().GetAddress());
4038
0
4039
0
  if(!IsParsingWithSipccParser()) {
4040
0
    // All following AddMediaSection calls are expected to fail
4041
0
    // SdpMediaSection::kDccpRtpAvp is expected to cause a failure
4042
0
    mSdp->AddMediaSection(SdpMediaSection::kAudio,
4043
0
                          SdpDirectionAttribute::Direction::kSendonly,
4044
0
                          14006, SdpMediaSection::kDccpRtpAvp, sdp::kIPv6,
4045
0
                          "2607:f8b0:4004:801::2013");
4046
0
    ASSERT_EQ(5U, mSdp->GetMediaSectionCount())
4047
0
      << "Wrong number of media sections after adding media section";
4048
0
4049
0
    // sdp::kAddrTypeNone is expected to cause a failure
4050
0
    mSdp->AddMediaSection(SdpMediaSection::kAudio,
4051
0
                          SdpDirectionAttribute::Direction::kSendonly,
4052
0
                          14006, SdpMediaSection::kDtlsSctp, sdp::kAddrTypeNone,
4053
0
                          "2607:f8b0:4004:801::2013");
4054
0
    ASSERT_EQ(5U, mSdp->GetMediaSectionCount())
4055
0
      << "Wrong number of media sections after adding media section";
4056
0
4057
0
    // "NOT:AN.IP.ADDRESS" is expected to cause a failure
4058
0
    mSdp->AddMediaSection(SdpMediaSection::kAudio,
4059
0
                          SdpDirectionAttribute::Direction::kSendonly,
4060
0
                          14006, SdpMediaSection::kTcpTlsRtpSavpf, sdp::kIPv6,
4061
0
                          "NOT:AN.IP.ADDRESS");
4062
0
    ASSERT_EQ(5U, mSdp->GetMediaSectionCount())
4063
0
      << "Wrong number of media sections after adding media section";
4064
0
  }
4065
0
}
4066
4067
0
TEST_P(NewSdpTest, CheckAddDataChannel_Draft05) {
4068
0
  // Parse any valid sdp with a media section
4069
0
  ParseSdp("v=0" CRLF
4070
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
4071
0
           "s=SIP Call" CRLF
4072
0
           "c=IN IP4 198.51.100.7" CRLF
4073
0
           "b=CT:5000" CRLF
4074
0
           "t=0 0" CRLF
4075
0
           "m=application 56436 DTLS/SCTP 5000" CRLF);
4076
0
4077
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
4078
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount());
4079
0
4080
0
  auto& mediaSection = mSdp->GetMediaSection(0);
4081
0
  mediaSection.AddDataChannel("webrtc-datachannel", 6000, 16, 0);
4082
0
4083
0
  ASSERT_FALSE(mediaSection.GetAttributeList().
4084
0
              HasAttribute(SdpAttribute::kMaxMessageSizeAttribute));
4085
0
  ASSERT_TRUE(mediaSection.GetAttributeList().
4086
0
              HasAttribute(SdpAttribute::kSctpmapAttribute));
4087
0
  ASSERT_TRUE(mediaSection.GetAttributeList().GetSctpmap().HasEntry("6000"));
4088
0
  ASSERT_EQ(16U, mediaSection.GetAttributeList().
4089
0
                 GetSctpmap().GetFirstEntry().streams);
4090
0
  ASSERT_EQ("webrtc-datachannel", mediaSection.GetAttributeList().
4091
0
                                  GetSctpmap().GetFirstEntry().name);
4092
0
4093
0
  mediaSection.AddDataChannel("webrtc-datachannel", 15000, 8, 1800);
4094
0
4095
0
  ASSERT_TRUE(mediaSection.GetAttributeList().
4096
0
              HasAttribute(SdpAttribute::kMaxMessageSizeAttribute));
4097
0
  ASSERT_EQ(1800U, mediaSection.GetAttributeList().GetMaxMessageSize());
4098
0
  ASSERT_TRUE(mediaSection.GetAttributeList().
4099
0
              HasAttribute(SdpAttribute::kSctpmapAttribute));
4100
0
  ASSERT_TRUE(mediaSection.GetAttributeList().GetSctpmap().HasEntry("15000"));
4101
0
  ASSERT_EQ(8U, mediaSection.GetAttributeList().
4102
0
                GetSctpmap().GetFirstEntry().streams);
4103
0
}
4104
4105
0
TEST_P(NewSdpTest, CheckAddDataChannel) {
4106
0
  ParseSdp("v=0" CRLF
4107
0
           "o=- 4294967296 2 IN IP4 127.0.0.1" CRLF
4108
0
           "s=SIP Call" CRLF
4109
0
           "c=IN IP4 198.51.100.7" CRLF
4110
0
           "b=CT:5000" CRLF
4111
0
           "t=0 0" CRLF
4112
0
           "m=application 56436 UDP/DTLS/SCTP webrtc-datachannel" CRLF);
4113
0
4114
0
  ASSERT_TRUE(!!mSdp) << "Parse failed: " << GetParseErrors();
4115
0
  ASSERT_EQ(1U, mSdp->GetMediaSectionCount());
4116
0
4117
0
  auto& mediaSection = mSdp->GetMediaSection(0);
4118
0
  mediaSection.AddDataChannel("webrtc-datachannel", 6000, 16, 0);
4119
0
4120
0
  ASSERT_FALSE(mediaSection.GetAttributeList().
4121
0
              HasAttribute(SdpAttribute::kMaxMessageSizeAttribute));
4122
0
  ASSERT_TRUE(mediaSection.GetAttributeList().
4123
0
              HasAttribute(SdpAttribute::kSctpPortAttribute));
4124
0
  ASSERT_EQ(6000U, mediaSection.GetAttributeList().GetSctpPort());
4125
0
4126
0
  mediaSection.AddDataChannel("webrtc-datachannel", 15000, 8, 1800);
4127
0
4128
0
  ASSERT_TRUE(mediaSection.GetAttributeList().
4129
0
              HasAttribute(SdpAttribute::kMaxMessageSizeAttribute));
4130
0
  ASSERT_EQ(1800U, mediaSection.GetAttributeList().GetMaxMessageSize());
4131
0
  ASSERT_TRUE(mediaSection.GetAttributeList().
4132
0
              HasAttribute(SdpAttribute::kSctpPortAttribute));
4133
0
  ASSERT_EQ(15000U, mediaSection.GetAttributeList().GetSctpPort());
4134
0
}
4135
4136
0
TEST(NewSdpTestNoFixture, CheckParsingResultComparer) {
4137
0
  auto check_comparison = [] (const std::string sdp_string) {
4138
0
    SipccSdpParser sipccParser;
4139
0
    RsdparsaSdpParser rustParser;
4140
0
4141
0
    auto sipccSdp = sipccParser.Parse(sdp_string);
4142
0
    auto rustSdp = rustParser.Parse(sdp_string);
4143
0
4144
0
    ParsingResultComparer comparer;
4145
0
    return comparer.Compare(*rustSdp, *sipccSdp, sdp_string);
4146
0
  };
4147
0
4148
0
  ASSERT_TRUE(check_comparison(kBasicAudioVideoOffer));
4149
0
  ASSERT_TRUE(check_comparison(kH264AudioVideoOffer));
4150
0
4151
0
  // Check the Fmtp comprison
4152
0
  const std::string kBasicOpusFmtp1 =
4153
0
  "v=0" CRLF
4154
0
  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
4155
0
  "s=SIP Call" CRLF
4156
0
  "c=IN IP4 224.0.0.1/100/12" CRLF
4157
0
  "t=0 0" CRLF
4158
0
  "m=video 9 RTP/SAVPF 120" CRLF
4159
0
  "a=rtpmap:120 opus/48000" CRLF
4160
0
  "a=fmtp:120 stereo=1;useinbandfec=1" CRLF;
4161
0
  ASSERT_TRUE(check_comparison(kBasicOpusFmtp1));
4162
0
4163
0
  const std::string kBasicOpusFmtp2 =
4164
0
  "v=0" CRLF
4165
0
  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
4166
0
  "s=SIP Call" CRLF
4167
0
  "c=IN IP4 224.0.0.1/100/12" CRLF
4168
0
  "t=0 0" CRLF
4169
0
  "m=video 9 RTP/SAVPF 120" CRLF
4170
0
  "a=rtpmap:120 opus/48000" CRLF
4171
0
  "a=fmtp:120 useinbandfec=1;stereo=1;maxplaybackrate=32000" CRLF;
4172
0
  ASSERT_TRUE(check_comparison(kBasicOpusFmtp2));
4173
0
4174
0
  const std::string kBasicVP8Fmtp1 =
4175
0
  "v=0" CRLF
4176
0
  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
4177
0
  "s=SIP Call" CRLF
4178
0
  "c=IN IP4 224.0.0.1/100/12" CRLF
4179
0
  "t=0 0" CRLF
4180
0
  "m=video 9 RTP/SAVPF 120" CRLF
4181
0
  "a=rtpmap:120 VP8/90000" CRLF
4182
0
  "a=fmtp:120 max-fs=3600;max-fr=60" CRLF;
4183
0
  ASSERT_TRUE(check_comparison(kBasicVP8Fmtp1));
4184
0
  //
4185
0
  const std::string kBasicVP8Fmtp2 =
4186
0
  "v=0" CRLF
4187
0
  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
4188
0
  "s=SIP Call" CRLF
4189
0
  "c=IN IP4 224.0.0.1/100/12" CRLF
4190
0
  "t=0 0" CRLF
4191
0
  "m=video 9 RTP/SAVPF 120" CRLF
4192
0
  "a=rtpmap:120 VP8/90000" CRLF
4193
0
  "a=fmtp:120 max-fr=60;max-fs=3600" CRLF;
4194
0
  ASSERT_TRUE(check_comparison(kBasicVP8Fmtp2));
4195
0
4196
0
  const std::string kBasicH264Fmtp1 =
4197
0
  "v=0" CRLF
4198
0
  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
4199
0
  "s=SIP Call" CRLF
4200
0
  "c=IN IP4 224.0.0.1/100/12" CRLF
4201
0
  "t=0 0" CRLF
4202
0
  "m=video 9 RTP/SAVPF 120" CRLF
4203
0
  "a=rtpmap:120 H264/90000" CRLF
4204
0
  "a=fmtp:120 profile-level-id=42a01e;level_asymmetry_allowed=1" CRLF;
4205
0
  ASSERT_TRUE(check_comparison(kBasicH264Fmtp1));
4206
0
4207
0
  const std::string kBasicH264Fmtp2 =
4208
0
  "v=0" CRLF
4209
0
  "o=Mozilla-SIPUA-35.0a1 5184 0 IN IP4 0.0.0.0" CRLF
4210
0
  "s=SIP Call" CRLF
4211
0
  "c=IN IP4 224.0.0.1/100/12" CRLF
4212
0
  "t=0 0" CRLF
4213
0
  "m=video 9 RTP/SAVPF 120" CRLF
4214
0
  "a=rtpmap:120 H264/90000" CRLF
4215
0
  "a=fmtp:120 level_asymmetry_allowed=1;profile-level-id=42a01e;max_fs=3600" CRLF;
4216
0
  ASSERT_TRUE(check_comparison(kBasicH264Fmtp2));
4217
0
}
4218
4219
0
TEST(NewSdpTestNoFixture, CheckAttributeTypeSerialize) {
4220
0
  for (auto a = static_cast<size_t>(SdpAttribute::kFirstAttribute);
4221
0
       a <= static_cast<size_t>(SdpAttribute::kLastAttribute);
4222
0
       ++a) {
4223
0
4224
0
    SdpAttribute::AttributeType type =
4225
0
      static_cast<SdpAttribute::AttributeType>(a);
4226
0
4227
0
    // Direction attributes are handled a little differently
4228
0
    if (type != SdpAttribute::kDirectionAttribute) {
4229
0
      std::ostringstream os;
4230
0
      os << type;
4231
0
      ASSERT_NE("", os.str());
4232
0
    }
4233
0
  }
4234
0
}
4235
4236
static SdpImageattrAttributeList::XYRange
4237
ParseXYRange(const std::string& input)
4238
0
{
4239
0
  std::istringstream is(input + ",");
4240
0
  std::string error;
4241
0
  SdpImageattrAttributeList::XYRange range;
4242
0
  EXPECT_TRUE(range.Parse(is, &error)) << error;
4243
0
  EXPECT_EQ(',', is.get());
4244
0
  EXPECT_EQ(EOF, is.get());
4245
0
  return range;
4246
0
}
4247
4248
TEST(NewSdpTestNoFixture, CheckImageattrXYRangeParseValid)
4249
0
{
4250
0
  {
4251
0
    SdpImageattrAttributeList::XYRange range(ParseXYRange("640"));
4252
0
    ASSERT_EQ(1U, range.discreteValues.size());
4253
0
    ASSERT_EQ(640U, range.discreteValues[0]);
4254
0
  }
4255
0
4256
0
  {
4257
0
    SdpImageattrAttributeList::XYRange range(ParseXYRange("[320,640]"));
4258
0
    ASSERT_EQ(2U, range.discreteValues.size());
4259
0
    ASSERT_EQ(320U, range.discreteValues[0]);
4260
0
    ASSERT_EQ(640U, range.discreteValues[1]);
4261
0
  }
4262
0
4263
0
  {
4264
0
    SdpImageattrAttributeList::XYRange range(ParseXYRange("[320,640,1024]"));
4265
0
    ASSERT_EQ(3U, range.discreteValues.size());
4266
0
    ASSERT_EQ(320U, range.discreteValues[0]);
4267
0
    ASSERT_EQ(640U, range.discreteValues[1]);
4268
0
    ASSERT_EQ(1024U, range.discreteValues[2]);
4269
0
  }
4270
0
4271
0
  {
4272
0
    SdpImageattrAttributeList::XYRange range(ParseXYRange("[320:640]"));
4273
0
    ASSERT_EQ(0U, range.discreteValues.size());
4274
0
    ASSERT_EQ(320U, range.min);
4275
0
    ASSERT_EQ(1U, range.step);
4276
0
    ASSERT_EQ(640U, range.max);
4277
0
  }
4278
0
4279
0
  {
4280
0
    SdpImageattrAttributeList::XYRange range(ParseXYRange("[320:16:640]"));
4281
0
    ASSERT_EQ(0U, range.discreteValues.size());
4282
0
    ASSERT_EQ(320U, range.min);
4283
0
    ASSERT_EQ(16U, range.step);
4284
0
    ASSERT_EQ(640U, range.max);
4285
0
  }
4286
0
}
4287
4288
template<typename T>
4289
void
4290
ParseInvalid(const std::string& input, size_t last)
4291
0
{
4292
0
  std::istringstream is(input);
4293
0
  T parsed;
4294
0
  std::string error;
4295
0
  ASSERT_FALSE(parsed.Parse(is, &error))
4296
0
    << "\'" << input << "\' should not have parsed successfully";
4297
0
  is.clear();
4298
0
  ASSERT_EQ(last, static_cast<size_t>(is.tellg()))
4299
0
    << "Parse failed at unexpected location:" << std::endl
4300
0
    << input << std::endl
4301
0
    << std::string(is.tellg(), ' ') << "^" << std::endl;
4302
0
  // For a human to eyeball to make sure the error strings look sane
4303
0
  std::cout << "\"" << input << "\" - " << error << std::endl; \
4304
0
}
Unexecuted instantiation: void test::ParseInvalid<mozilla::SdpImageattrAttributeList::XYRange>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Unexecuted instantiation: void test::ParseInvalid<mozilla::SdpImageattrAttributeList::SRange>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Unexecuted instantiation: void test::ParseInvalid<mozilla::SdpImageattrAttributeList::PRange>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Unexecuted instantiation: void test::ParseInvalid<mozilla::SdpImageattrAttributeList::Set>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Unexecuted instantiation: void test::ParseInvalid<mozilla::SdpImageattrAttributeList::Imageattr>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Unexecuted instantiation: void test::ParseInvalid<mozilla::SdpSimulcastAttribute::Version>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Unexecuted instantiation: void test::ParseInvalid<mozilla::SdpSimulcastAttribute::Versions>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Unexecuted instantiation: void test::ParseInvalid<mozilla::SdpSimulcastAttribute>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
Unexecuted instantiation: void test::ParseInvalid<mozilla::SdpRidAttributeList::Rid>(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long)
4305
4306
TEST(NewSdpTestNoFixture, CheckImageattrXYRangeParseInvalid)
4307
0
{
4308
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[-1", 1);
4309
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[-", 1);
4310
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[-v", 1);
4311
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:-1", 5);
4312
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:16:-1", 8);
4313
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640,-1", 5);
4314
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640,-]", 5);
4315
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("-v", 0);
4316
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("-1", 0);
4317
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("", 0);
4318
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[", 1);
4319
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[v", 1);
4320
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[", 1);
4321
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[ 640", 1);
4322
0
  // It looks like the overflow detection only happens once the whole number
4323
0
  // is scanned...
4324
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[99999999999999999:", 18);
4325
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640", 4);
4326
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:", 5);
4327
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:v", 5);
4328
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:16", 7);
4329
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:16:", 8);
4330
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:16:v", 8);
4331
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:16:320]", 11);
4332
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:16:320", 11);
4333
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:16:320v", 11);
4334
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:1024", 9);
4335
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:320]", 8);
4336
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640:1024v", 9);
4337
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640,", 5);
4338
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640,v", 5);
4339
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640]", 4);
4340
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640x", 4);
4341
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("[640,]", 5);
4342
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>(" ", 0);
4343
0
  ParseInvalid<SdpImageattrAttributeList::XYRange>("v", 0);
4344
0
}
4345
4346
static SdpImageattrAttributeList::SRange
4347
ParseSRange(const std::string& input)
4348
0
{
4349
0
  std::istringstream is(input + ",");
4350
0
  std::string error;
4351
0
  SdpImageattrAttributeList::SRange range;
4352
0
  EXPECT_TRUE(range.Parse(is, &error)) << error;
4353
0
  EXPECT_EQ(',', is.get());
4354
0
  EXPECT_EQ(EOF, is.get());
4355
0
  return range;
4356
0
}
4357
4358
TEST(NewSdpTestNoFixture, CheckImageattrSRangeParseValid)
4359
0
{
4360
0
  {
4361
0
    SdpImageattrAttributeList::SRange range(ParseSRange("0.1"));
4362
0
    ASSERT_EQ(1U, range.discreteValues.size());
4363
0
    ASSERT_FLOAT_EQ(0.1f, range.discreteValues[0]);
4364
0
  }
4365
0
4366
0
  {
4367
0
    SdpImageattrAttributeList::SRange range(ParseSRange("[0.1,0.2]"));
4368
0
    ASSERT_EQ(2U, range.discreteValues.size());
4369
0
    ASSERT_FLOAT_EQ(0.1f, range.discreteValues[0]);
4370
0
    ASSERT_FLOAT_EQ(0.2f, range.discreteValues[1]);
4371
0
  }
4372
0
4373
0
  {
4374
0
    SdpImageattrAttributeList::SRange range(ParseSRange("[0.1,0.2,0.3]"));
4375
0
    ASSERT_EQ(3U, range.discreteValues.size());
4376
0
    ASSERT_FLOAT_EQ(0.1f, range.discreteValues[0]);
4377
0
    ASSERT_FLOAT_EQ(0.2f, range.discreteValues[1]);
4378
0
    ASSERT_FLOAT_EQ(0.3f, range.discreteValues[2]);
4379
0
  }
4380
0
4381
0
  {
4382
0
    SdpImageattrAttributeList::SRange range(ParseSRange("[0.1-0.2]"));
4383
0
    ASSERT_EQ(0U, range.discreteValues.size());
4384
0
    ASSERT_FLOAT_EQ(0.1f, range.min);
4385
0
    ASSERT_FLOAT_EQ(0.2f, range.max);
4386
0
  }
4387
0
}
4388
4389
TEST(NewSdpTestNoFixture, CheckImageattrSRangeParseInvalid)
4390
0
{
4391
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("", 0);
4392
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[", 1);
4393
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[v", 1);
4394
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[-1", 1);
4395
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[", 1);
4396
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[-", 1);
4397
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[v", 1);
4398
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[ 0.2", 1);
4399
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[10.1-", 5);
4400
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.08-", 5);
4401
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2", 4);
4402
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2-", 5);
4403
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2-v", 5);
4404
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2--1", 5);
4405
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2-0.3", 8);
4406
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2-0.1]", 8);
4407
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2-0.3v", 8);
4408
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2,", 5);
4409
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2,v", 5);
4410
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2,-1", 5);
4411
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2]", 4);
4412
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2v", 4);
4413
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2,]", 5);
4414
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("[0.2,-]", 5);
4415
0
  ParseInvalid<SdpImageattrAttributeList::SRange>(" ", 0);
4416
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("v", 0);
4417
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("-v", 0);
4418
0
  ParseInvalid<SdpImageattrAttributeList::SRange>("-1", 0);
4419
0
}
4420
4421
static SdpImageattrAttributeList::PRange
4422
ParsePRange(const std::string& input)
4423
0
{
4424
0
  std::istringstream is(input + ",");
4425
0
  std::string error;
4426
0
  SdpImageattrAttributeList::PRange range;
4427
0
  EXPECT_TRUE(range.Parse(is, &error)) << error;
4428
0
  EXPECT_EQ(',', is.get());
4429
0
  EXPECT_EQ(EOF, is.get());
4430
0
  return range;
4431
0
}
4432
4433
TEST(NewSdpTestNoFixture, CheckImageattrPRangeParseValid)
4434
0
{
4435
0
  SdpImageattrAttributeList::PRange range(ParsePRange("[0.1000-9.9999]"));
4436
0
  ASSERT_FLOAT_EQ(0.1f, range.min);
4437
0
  ASSERT_FLOAT_EQ(9.9999f, range.max);
4438
0
}
4439
4440
TEST(NewSdpTestNoFixture, CheckImageattrPRangeParseInvalid)
4441
0
{
4442
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("", 0);
4443
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[", 1);
4444
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[v", 1);
4445
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[-1", 1);
4446
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[", 1);
4447
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[-", 1);
4448
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[v", 1);
4449
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[ 0.2", 1);
4450
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[10.1-", 5);
4451
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.08-", 5);
4452
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2", 4);
4453
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2-", 5);
4454
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2-v", 5);
4455
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2--1", 5);
4456
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2-0.3", 8);
4457
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2-0.1]", 8);
4458
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2-0.3v", 8);
4459
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2,", 4);
4460
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2:", 4);
4461
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2]", 4);
4462
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("[0.2v", 4);
4463
0
  ParseInvalid<SdpImageattrAttributeList::PRange>(" ", 0);
4464
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("v", 0);
4465
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("-x", 0);
4466
0
  ParseInvalid<SdpImageattrAttributeList::PRange>("-1", 0);
4467
0
}
4468
4469
static SdpImageattrAttributeList::Set
4470
ParseSet(const std::string& input)
4471
0
{
4472
0
  std::istringstream is(input + " ");
4473
0
  std::string error;
4474
0
  SdpImageattrAttributeList::Set set;
4475
0
  EXPECT_TRUE(set.Parse(is, &error)) << error;
4476
0
  EXPECT_EQ(' ', is.get());
4477
0
  EXPECT_EQ(EOF, is.get());
4478
0
  return set;
4479
0
}
4480
4481
TEST(NewSdpTestNoFixture, CheckImageattrSetParseValid)
4482
0
{
4483
0
  {
4484
0
    SdpImageattrAttributeList::Set set(ParseSet("[x=320,y=240]"));
4485
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4486
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4487
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4488
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4489
0
    ASSERT_FALSE(set.sRange.IsSet());
4490
0
    ASSERT_FALSE(set.pRange.IsSet());
4491
0
    ASSERT_FLOAT_EQ(0.5f, set.qValue);
4492
0
  }
4493
0
4494
0
  {
4495
0
    SdpImageattrAttributeList::Set set(ParseSet("[X=320,Y=240]"));
4496
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4497
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4498
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4499
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4500
0
    ASSERT_FALSE(set.sRange.IsSet());
4501
0
    ASSERT_FALSE(set.pRange.IsSet());
4502
0
    ASSERT_FLOAT_EQ(0.5f, set.qValue);
4503
0
  }
4504
0
4505
0
  {
4506
0
    SdpImageattrAttributeList::Set set(ParseSet("[x=320,y=240,par=[0.1-0.2]]"));
4507
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4508
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4509
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4510
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4511
0
    ASSERT_FALSE(set.sRange.IsSet());
4512
0
    ASSERT_TRUE(set.pRange.IsSet());
4513
0
    ASSERT_FLOAT_EQ(0.1f, set.pRange.min);
4514
0
    ASSERT_FLOAT_EQ(0.2f, set.pRange.max);
4515
0
    ASSERT_FLOAT_EQ(0.5f, set.qValue);
4516
0
  }
4517
0
4518
0
  {
4519
0
    SdpImageattrAttributeList::Set set(ParseSet("[x=320,y=240,sar=[0.1-0.2]]"));
4520
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4521
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4522
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4523
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4524
0
    ASSERT_TRUE(set.sRange.IsSet());
4525
0
    ASSERT_FLOAT_EQ(0.1f, set.sRange.min);
4526
0
    ASSERT_FLOAT_EQ(0.2f, set.sRange.max);
4527
0
    ASSERT_FALSE(set.pRange.IsSet());
4528
0
    ASSERT_FLOAT_EQ(0.5f, set.qValue);
4529
0
  }
4530
0
4531
0
  {
4532
0
    SdpImageattrAttributeList::Set set(ParseSet("[x=320,y=240,q=0.1]"));
4533
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4534
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4535
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4536
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4537
0
    ASSERT_FALSE(set.sRange.IsSet());
4538
0
    ASSERT_FALSE(set.pRange.IsSet());
4539
0
    ASSERT_FLOAT_EQ(0.1f, set.qValue);
4540
0
  }
4541
0
4542
0
  {
4543
0
    SdpImageattrAttributeList::Set set(
4544
0
        ParseSet("[x=320,y=240,par=[0.1-0.2],sar=[0.3-0.4],q=0.6]"));
4545
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4546
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4547
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4548
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4549
0
    ASSERT_TRUE(set.sRange.IsSet());
4550
0
    ASSERT_FLOAT_EQ(0.3f, set.sRange.min);
4551
0
    ASSERT_FLOAT_EQ(0.4f, set.sRange.max);
4552
0
    ASSERT_TRUE(set.pRange.IsSet());
4553
0
    ASSERT_FLOAT_EQ(0.1f, set.pRange.min);
4554
0
    ASSERT_FLOAT_EQ(0.2f, set.pRange.max);
4555
0
    ASSERT_FLOAT_EQ(0.6f, set.qValue);
4556
0
  }
4557
0
4558
0
  {
4559
0
    SdpImageattrAttributeList::Set set(ParseSet("[x=320,y=240,foo=bar,q=0.1]"));
4560
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4561
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4562
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4563
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4564
0
    ASSERT_FALSE(set.sRange.IsSet());
4565
0
    ASSERT_FALSE(set.pRange.IsSet());
4566
0
    ASSERT_FLOAT_EQ(0.1f, set.qValue);
4567
0
  }
4568
0
4569
0
  {
4570
0
    SdpImageattrAttributeList::Set set(
4571
0
        ParseSet("[x=320,y=240,foo=bar,q=0.1,bar=baz]"));
4572
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4573
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4574
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4575
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4576
0
    ASSERT_FALSE(set.sRange.IsSet());
4577
0
    ASSERT_FALSE(set.pRange.IsSet());
4578
0
    ASSERT_FLOAT_EQ(0.1f, set.qValue);
4579
0
  }
4580
0
4581
0
  {
4582
0
    SdpImageattrAttributeList::Set set(
4583
0
        ParseSet("[x=320,y=240,foo=[bar],q=0.1,bar=[baz]]"));
4584
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4585
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4586
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4587
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4588
0
    ASSERT_FALSE(set.sRange.IsSet());
4589
0
    ASSERT_FALSE(set.pRange.IsSet());
4590
0
    ASSERT_FLOAT_EQ(0.1f, set.qValue);
4591
0
  }
4592
0
4593
0
  {
4594
0
    SdpImageattrAttributeList::Set set(
4595
0
        ParseSet("[x=320,y=240,foo=[par=foo,sar=bar],q=0.1,bar=[baz]]"));
4596
0
    ASSERT_EQ(1U, set.xRange.discreteValues.size());
4597
0
    ASSERT_EQ(320U, set.xRange.discreteValues[0]);
4598
0
    ASSERT_EQ(1U, set.yRange.discreteValues.size());
4599
0
    ASSERT_EQ(240U, set.yRange.discreteValues[0]);
4600
0
    ASSERT_FALSE(set.sRange.IsSet());
4601
0
    ASSERT_FALSE(set.pRange.IsSet());
4602
0
    ASSERT_FLOAT_EQ(0.1f, set.qValue);
4603
0
  }
4604
0
}
4605
4606
TEST(NewSdpTestNoFixture, CheckImageattrSetParseInvalid)
4607
0
{
4608
0
  ParseInvalid<SdpImageattrAttributeList::Set>("", 0);
4609
0
  ParseInvalid<SdpImageattrAttributeList::Set>("x", 0);
4610
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[", 1);
4611
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[=", 2);
4612
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x", 2);
4613
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[y=", 3);
4614
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=[", 4);
4615
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320", 6);
4616
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320v", 6);
4617
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,", 7);
4618
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,=", 8);
4619
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,x", 8);
4620
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,x=", 9);
4621
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=[", 10);
4622
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240", 12);
4623
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240x", 12);
4624
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,", 13);
4625
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,q=", 15);
4626
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,q=v", 15);
4627
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,q=0.5", 18);
4628
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,q=0.5,", 19);
4629
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,q=0.5,]", 20);
4630
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,q=0.5,=]", 20);
4631
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,q=0.5,sar=v]", 23);
4632
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,q=0.5,q=0.4", 21);
4633
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,sar=", 17);
4634
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,sar=v", 17);
4635
0
  ParseInvalid<SdpImageattrAttributeList::Set>(
4636
0
      "[x=320,y=240,sar=[0.5-0.6],sar=[0.7-0.8]", 31);
4637
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,par=", 17);
4638
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,par=x", 17);
4639
0
  ParseInvalid<SdpImageattrAttributeList::Set>(
4640
0
      "[x=320,y=240,par=[0.5-0.6],par=[0.7-0.8]", 31);
4641
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,foo=", 17);
4642
0
  ParseInvalid<SdpImageattrAttributeList::Set>("[x=320,y=240,foo=x", 18);
4643
0
}
4644
4645
static SdpImageattrAttributeList::Imageattr
4646
ParseImageattr(const std::string& input)
4647
0
{
4648
0
  std::istringstream is(input);
4649
0
  std::string error;
4650
0
  SdpImageattrAttributeList::Imageattr imageattr;
4651
0
  EXPECT_TRUE(imageattr.Parse(is, &error)) << error;
4652
0
  EXPECT_TRUE(is.eof());
4653
0
  return imageattr;
4654
0
}
4655
4656
TEST(NewSdpTestNoFixture, CheckImageattrParseValid)
4657
0
{
4658
0
  {
4659
0
    SdpImageattrAttributeList::Imageattr imageattr(ParseImageattr("* send *"));
4660
0
    ASSERT_FALSE(imageattr.pt.isSome());
4661
0
    ASSERT_TRUE(imageattr.sendAll);
4662
0
    ASSERT_TRUE(imageattr.sendSets.empty());
4663
0
    ASSERT_FALSE(imageattr.recvAll);
4664
0
    ASSERT_TRUE(imageattr.recvSets.empty());
4665
0
  }
4666
0
4667
0
  {
4668
0
    SdpImageattrAttributeList::Imageattr imageattr(ParseImageattr("* SEND *"));
4669
0
    ASSERT_FALSE(imageattr.pt.isSome());
4670
0
    ASSERT_TRUE(imageattr.sendAll);
4671
0
    ASSERT_TRUE(imageattr.sendSets.empty());
4672
0
    ASSERT_FALSE(imageattr.recvAll);
4673
0
    ASSERT_TRUE(imageattr.recvSets.empty());
4674
0
  }
4675
0
4676
0
  {
4677
0
    SdpImageattrAttributeList::Imageattr imageattr(ParseImageattr("* recv *"));
4678
0
    ASSERT_FALSE(imageattr.pt.isSome());
4679
0
    ASSERT_FALSE(imageattr.sendAll);
4680
0
    ASSERT_TRUE(imageattr.sendSets.empty());
4681
0
    ASSERT_TRUE(imageattr.recvAll);
4682
0
    ASSERT_TRUE(imageattr.recvSets.empty());
4683
0
  }
4684
0
4685
0
  {
4686
0
    SdpImageattrAttributeList::Imageattr imageattr(ParseImageattr("* RECV *"));
4687
0
    ASSERT_FALSE(imageattr.pt.isSome());
4688
0
    ASSERT_FALSE(imageattr.sendAll);
4689
0
    ASSERT_TRUE(imageattr.sendSets.empty());
4690
0
    ASSERT_TRUE(imageattr.recvAll);
4691
0
    ASSERT_TRUE(imageattr.recvSets.empty());
4692
0
  }
4693
0
4694
0
  {
4695
0
    SdpImageattrAttributeList::Imageattr imageattr(
4696
0
        ParseImageattr("* recv * send *"));
4697
0
    ASSERT_FALSE(imageattr.pt.isSome());
4698
0
    ASSERT_TRUE(imageattr.sendAll);
4699
0
    ASSERT_TRUE(imageattr.sendSets.empty());
4700
0
    ASSERT_TRUE(imageattr.recvAll);
4701
0
    ASSERT_TRUE(imageattr.recvSets.empty());
4702
0
  }
4703
0
4704
0
  {
4705
0
    SdpImageattrAttributeList::Imageattr imageattr(
4706
0
        ParseImageattr("* send * recv *"));
4707
0
    ASSERT_FALSE(imageattr.pt.isSome());
4708
0
    ASSERT_TRUE(imageattr.sendAll);
4709
0
    ASSERT_TRUE(imageattr.sendSets.empty());
4710
0
    ASSERT_TRUE(imageattr.recvAll);
4711
0
    ASSERT_TRUE(imageattr.recvSets.empty());
4712
0
  }
4713
0
4714
0
  {
4715
0
    SdpImageattrAttributeList::Imageattr imageattr(
4716
0
        ParseImageattr("8 send * recv *"));
4717
0
    ASSERT_EQ(8U, *imageattr.pt);
4718
0
    ASSERT_TRUE(imageattr.sendAll);
4719
0
    ASSERT_TRUE(imageattr.sendSets.empty());
4720
0
    ASSERT_TRUE(imageattr.recvAll);
4721
0
    ASSERT_TRUE(imageattr.recvSets.empty());
4722
0
  }
4723
0
4724
0
  {
4725
0
    SdpImageattrAttributeList::Imageattr imageattr(
4726
0
        ParseImageattr("8 send [x=320,y=240] recv *"));
4727
0
    ASSERT_EQ(8U, *imageattr.pt);
4728
0
    ASSERT_FALSE(imageattr.sendAll);
4729
0
    ASSERT_EQ(1U, imageattr.sendSets.size());
4730
0
    ASSERT_EQ(1U, imageattr.sendSets[0].xRange.discreteValues.size());
4731
0
    ASSERT_EQ(320U, imageattr.sendSets[0].xRange.discreteValues[0]);
4732
0
    ASSERT_EQ(1U, imageattr.sendSets[0].yRange.discreteValues.size());
4733
0
    ASSERT_EQ(240U, imageattr.sendSets[0].yRange.discreteValues[0]);
4734
0
    ASSERT_TRUE(imageattr.recvAll);
4735
0
    ASSERT_TRUE(imageattr.recvSets.empty());
4736
0
  }
4737
0
4738
0
  {
4739
0
    SdpImageattrAttributeList::Imageattr imageattr(
4740
0
        ParseImageattr("8 send [x=320,y=240] [x=640,y=480] recv *"));
4741
0
    ASSERT_EQ(8U, *imageattr.pt);
4742
0
    ASSERT_FALSE(imageattr.sendAll);
4743
0
    ASSERT_EQ(2U, imageattr.sendSets.size());
4744
0
    ASSERT_EQ(1U, imageattr.sendSets[0].xRange.discreteValues.size());
4745
0
    ASSERT_EQ(320U, imageattr.sendSets[0].xRange.discreteValues[0]);
4746
0
    ASSERT_EQ(1U, imageattr.sendSets[0].yRange.discreteValues.size());
4747
0
    ASSERT_EQ(240U, imageattr.sendSets[0].yRange.discreteValues[0]);
4748
0
    ASSERT_EQ(1U, imageattr.sendSets[1].xRange.discreteValues.size());
4749
0
    ASSERT_EQ(640U, imageattr.sendSets[1].xRange.discreteValues[0]);
4750
0
    ASSERT_EQ(1U, imageattr.sendSets[1].yRange.discreteValues.size());
4751
0
    ASSERT_EQ(480U, imageattr.sendSets[1].yRange.discreteValues[0]);
4752
0
    ASSERT_TRUE(imageattr.recvAll);
4753
0
    ASSERT_TRUE(imageattr.recvSets.empty());
4754
0
  }
4755
0
4756
0
  {
4757
0
    SdpImageattrAttributeList::Imageattr imageattr(
4758
0
        ParseImageattr("8 send * recv [x=320,y=240]"));
4759
0
    ASSERT_EQ(8U, *imageattr.pt);
4760
0
    ASSERT_FALSE(imageattr.recvAll);
4761
0
    ASSERT_EQ(1U, imageattr.recvSets.size());
4762
0
    ASSERT_EQ(1U, imageattr.recvSets[0].xRange.discreteValues.size());
4763
0
    ASSERT_EQ(320U, imageattr.recvSets[0].xRange.discreteValues[0]);
4764
0
    ASSERT_EQ(1U, imageattr.recvSets[0].yRange.discreteValues.size());
4765
0
    ASSERT_EQ(240U, imageattr.recvSets[0].yRange.discreteValues[0]);
4766
0
    ASSERT_TRUE(imageattr.sendAll);
4767
0
    ASSERT_TRUE(imageattr.sendSets.empty());
4768
0
  }
4769
0
4770
0
  {
4771
0
    SdpImageattrAttributeList::Imageattr imageattr(
4772
0
        ParseImageattr("8 send * recv [x=320,y=240] [x=640,y=480]"));
4773
0
    ASSERT_EQ(8U, *imageattr.pt);
4774
0
    ASSERT_FALSE(imageattr.recvAll);
4775
0
    ASSERT_EQ(2U, imageattr.recvSets.size());
4776
0
    ASSERT_EQ(1U, imageattr.recvSets[0].xRange.discreteValues.size());
4777
0
    ASSERT_EQ(320U, imageattr.recvSets[0].xRange.discreteValues[0]);
4778
0
    ASSERT_EQ(1U, imageattr.recvSets[0].yRange.discreteValues.size());
4779
0
    ASSERT_EQ(240U, imageattr.recvSets[0].yRange.discreteValues[0]);
4780
0
    ASSERT_EQ(1U, imageattr.recvSets[1].xRange.discreteValues.size());
4781
0
    ASSERT_EQ(640U, imageattr.recvSets[1].xRange.discreteValues[0]);
4782
0
    ASSERT_EQ(1U, imageattr.recvSets[1].yRange.discreteValues.size());
4783
0
    ASSERT_EQ(480U, imageattr.recvSets[1].yRange.discreteValues[0]);
4784
0
    ASSERT_TRUE(imageattr.sendAll);
4785
0
    ASSERT_TRUE(imageattr.sendSets.empty());
4786
0
  }
4787
0
}
4788
4789
TEST(NewSdpTestNoFixture, CheckImageattrParseInvalid)
4790
0
{
4791
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("", 0);
4792
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>(" ", 0);
4793
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("-1", 0);
4794
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("99999 ", 5);
4795
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("*", 1);
4796
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("* sen", 5);
4797
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("* vcer *", 6);
4798
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("* send x", 7);
4799
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>(
4800
0
      "* send [x=640,y=480] [", 22);
4801
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("* send * sen", 12);
4802
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("* send * vcer *", 13);
4803
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("* send * send *", 13);
4804
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("* recv * recv *", 13);
4805
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>("* send * recv x", 14);
4806
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>(
4807
0
      "* send * recv [x=640,y=480] [", 29);
4808
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>(
4809
0
      "* send * recv [x=640,y=480] *", 28);
4810
0
  ParseInvalid<SdpImageattrAttributeList::Imageattr>(
4811
0
      "* send * recv [x=640,y=480] foobajooba", 28);
4812
0
}
4813
4814
TEST(NewSdpTestNoFixture, CheckImageattrXYRangeSerialization)
4815
0
{
4816
0
  SdpImageattrAttributeList::XYRange range;
4817
0
  std::stringstream os;
4818
0
4819
0
  range.min = 320;
4820
0
  range.max = 640;
4821
0
  range.Serialize(os);
4822
0
  ASSERT_EQ("[320:640]", os.str());
4823
0
  os.str(""); // clear
4824
0
4825
0
  range.step = 16;
4826
0
  range.Serialize(os);
4827
0
  ASSERT_EQ("[320:16:640]", os.str());
4828
0
  os.str(""); // clear
4829
0
4830
0
  range.min = 0;
4831
0
  range.max = 0;
4832
0
  range.discreteValues.push_back(320);
4833
0
  range.Serialize(os);
4834
0
  ASSERT_EQ("320", os.str());
4835
0
  os.str("");
4836
0
4837
0
  range.discreteValues.push_back(640);
4838
0
  range.Serialize(os);
4839
0
  ASSERT_EQ("[320,640]", os.str());
4840
0
}
4841
4842
TEST(NewSdpTestNoFixture, CheckImageattrSRangeSerialization)
4843
0
{
4844
0
  SdpImageattrAttributeList::SRange range;
4845
0
  std::ostringstream os;
4846
0
4847
0
  range.min = 0.1f;
4848
0
  range.max = 0.9999f;
4849
0
  range.Serialize(os);
4850
0
  ASSERT_EQ("[0.1000-0.9999]", os.str());
4851
0
  os.str("");
4852
0
4853
0
  range.min = 0.0f;
4854
0
  range.max = 0.0f;
4855
0
  range.discreteValues.push_back(0.1f);
4856
0
  range.Serialize(os);
4857
0
  ASSERT_EQ("0.1000", os.str());
4858
0
  os.str("");
4859
0
4860
0
  range.discreteValues.push_back(0.5f);
4861
0
  range.Serialize(os);
4862
0
  ASSERT_EQ("[0.1000,0.5000]", os.str());
4863
0
}
4864
4865
TEST(NewSdpTestNoFixture, CheckImageattrPRangeSerialization)
4866
0
{
4867
0
  SdpImageattrAttributeList::PRange range;
4868
0
  std::ostringstream os;
4869
0
4870
0
  range.min = 0.1f;
4871
0
  range.max = 0.9999f;
4872
0
  range.Serialize(os);
4873
0
  ASSERT_EQ("[0.1000-0.9999]", os.str());
4874
0
}
4875
4876
TEST(NewSdpTestNoFixture, CheckImageattrSetSerialization)
4877
0
{
4878
0
  SdpImageattrAttributeList::Set set;
4879
0
  std::ostringstream os;
4880
0
4881
0
  set.xRange.discreteValues.push_back(640);
4882
0
  set.yRange.discreteValues.push_back(480);
4883
0
  set.Serialize(os);
4884
0
  ASSERT_EQ("[x=640,y=480]", os.str());
4885
0
  os.str("");
4886
0
4887
0
  set.qValue = 0.00f;
4888
0
  set.Serialize(os);
4889
0
  ASSERT_EQ("[x=640,y=480,q=0.00]", os.str());
4890
0
  os.str("");
4891
0
4892
0
  set.qValue = 0.10f;
4893
0
  set.Serialize(os);
4894
0
  ASSERT_EQ("[x=640,y=480,q=0.10]", os.str());
4895
0
  os.str("");
4896
0
4897
0
  set.qValue = 1.00f;
4898
0
  set.Serialize(os);
4899
0
  ASSERT_EQ("[x=640,y=480,q=1.00]", os.str());
4900
0
  os.str("");
4901
0
4902
0
  set.sRange.discreteValues.push_back(1.1f);
4903
0
  set.Serialize(os);
4904
0
  ASSERT_EQ("[x=640,y=480,sar=1.1000,q=1.00]", os.str());
4905
0
  os.str("");
4906
0
4907
0
  set.pRange.min = 0.9f;
4908
0
  set.pRange.max = 1.1f;
4909
0
  set.Serialize(os);
4910
0
  ASSERT_EQ("[x=640,y=480,sar=1.1000,par=[0.9000-1.1000],q=1.00]", os.str());
4911
0
  os.str("");
4912
0
}
4913
4914
TEST(NewSdpTestNoFixture, CheckImageattrSerialization)
4915
0
{
4916
0
  SdpImageattrAttributeList::Imageattr imageattr;
4917
0
  std::ostringstream os;
4918
0
4919
0
  imageattr.sendAll = true;
4920
0
  imageattr.pt = Some<uint16_t>(8U);
4921
0
  imageattr.Serialize(os);
4922
0
  ASSERT_EQ("8 send *", os.str());
4923
0
  os.str("");
4924
0
4925
0
  imageattr.pt.reset();;
4926
0
  imageattr.Serialize(os);
4927
0
  ASSERT_EQ("* send *", os.str());
4928
0
  os.str("");
4929
0
4930
0
  imageattr.sendAll = false;
4931
0
  imageattr.recvAll = true;
4932
0
  imageattr.Serialize(os);
4933
0
  ASSERT_EQ("* recv *", os.str());
4934
0
  os.str("");
4935
0
4936
0
  imageattr.sendAll = true;
4937
0
  imageattr.Serialize(os);
4938
0
  ASSERT_EQ("* send * recv *", os.str());
4939
0
  os.str("");
4940
0
4941
0
  imageattr.sendAll = false;
4942
0
  imageattr.sendSets.push_back(SdpImageattrAttributeList::Set());
4943
0
  imageattr.sendSets.back().xRange.discreteValues.push_back(320);
4944
0
  imageattr.sendSets.back().yRange.discreteValues.push_back(240);
4945
0
  imageattr.Serialize(os);
4946
0
  ASSERT_EQ("* send [x=320,y=240] recv *", os.str());
4947
0
  os.str("");
4948
0
4949
0
  imageattr.sendSets.push_back(SdpImageattrAttributeList::Set());
4950
0
  imageattr.sendSets.back().xRange.discreteValues.push_back(640);
4951
0
  imageattr.sendSets.back().yRange.discreteValues.push_back(480);
4952
0
  imageattr.Serialize(os);
4953
0
  ASSERT_EQ("* send [x=320,y=240] [x=640,y=480] recv *", os.str());
4954
0
  os.str("");
4955
0
4956
0
  imageattr.recvAll = false;
4957
0
  imageattr.recvSets.push_back(SdpImageattrAttributeList::Set());
4958
0
  imageattr.recvSets.back().xRange.discreteValues.push_back(320);
4959
0
  imageattr.recvSets.back().yRange.discreteValues.push_back(240);
4960
0
  imageattr.Serialize(os);
4961
0
  ASSERT_EQ("* send [x=320,y=240] [x=640,y=480] recv [x=320,y=240]", os.str());
4962
0
  os.str("");
4963
0
4964
0
  imageattr.recvSets.push_back(SdpImageattrAttributeList::Set());
4965
0
  imageattr.recvSets.back().xRange.discreteValues.push_back(640);
4966
0
  imageattr.recvSets.back().yRange.discreteValues.push_back(480);
4967
0
  imageattr.Serialize(os);
4968
0
  ASSERT_EQ(
4969
0
      "* send [x=320,y=240] [x=640,y=480] recv [x=320,y=240] [x=640,y=480]",
4970
0
      os.str());
4971
0
  os.str("");
4972
0
}
4973
4974
TEST(NewSdpTestNoFixture, CheckSimulcastVersionSerialize)
4975
0
{
4976
0
  std::ostringstream os;
4977
0
4978
0
  SdpSimulcastAttribute::Version version;
4979
0
  version.choices.push_back("8");
4980
0
  version.Serialize(os);
4981
0
  ASSERT_EQ("8", os.str());
4982
0
  os.str("");
4983
0
4984
0
  version.choices.push_back("9");
4985
0
  version.Serialize(os);
4986
0
  ASSERT_EQ("8,9", os.str());
4987
0
  os.str("");
4988
0
4989
0
  version.choices.push_back("0");
4990
0
  version.Serialize(os);
4991
0
  ASSERT_EQ("8,9,0", os.str());
4992
0
  os.str("");
4993
0
}
4994
4995
static SdpSimulcastAttribute::Version
4996
ParseSimulcastVersion(const std::string& input)
4997
0
{
4998
0
  std::istringstream is(input + ";");
4999
0
  std::string error;
5000
0
  SdpSimulcastAttribute::Version version;
5001
0
  EXPECT_TRUE(version.Parse(is, &error)) << error;
5002
0
  EXPECT_EQ(';', is.get());
5003
0
  EXPECT_EQ(EOF, is.get());
5004
0
  return version;
5005
0
}
5006
5007
TEST(NewSdpTestNoFixture, CheckSimulcastVersionValidParse)
5008
0
{
5009
0
  {
5010
0
    SdpSimulcastAttribute::Version version(
5011
0
        ParseSimulcastVersion("1"));
5012
0
    ASSERT_EQ(1U, version.choices.size());
5013
0
    ASSERT_EQ("1", version.choices[0]);
5014
0
  }
5015
0
5016
0
  {
5017
0
    SdpSimulcastAttribute::Version version(
5018
0
        ParseSimulcastVersion("1,2"));
5019
0
    ASSERT_EQ(2U, version.choices.size());
5020
0
    ASSERT_EQ("1", version.choices[0]);
5021
0
    ASSERT_EQ("2", version.choices[1]);
5022
0
  }
5023
0
}
5024
5025
TEST(NewSdpTestNoFixture, CheckSimulcastVersionInvalidParse)
5026
0
{
5027
0
  ParseInvalid<SdpSimulcastAttribute::Version>("", 0);
5028
0
  ParseInvalid<SdpSimulcastAttribute::Version>(",", 0);
5029
0
  ParseInvalid<SdpSimulcastAttribute::Version>(";", 0);
5030
0
  ParseInvalid<SdpSimulcastAttribute::Version>(" ", 0);
5031
0
  ParseInvalid<SdpSimulcastAttribute::Version>("8,", 2);
5032
0
  ParseInvalid<SdpSimulcastAttribute::Version>("8, ", 2);
5033
0
  ParseInvalid<SdpSimulcastAttribute::Version>("8,,", 2);
5034
0
  ParseInvalid<SdpSimulcastAttribute::Version>("8,;", 2);
5035
0
}
5036
5037
TEST(NewSdpTestNoFixture, CheckSimulcastVersionsSerialize)
5038
0
{
5039
0
  std::ostringstream os;
5040
0
5041
0
  SdpSimulcastAttribute::Versions versions;
5042
0
  versions.type = SdpSimulcastAttribute::Versions::kPt;
5043
0
  versions.push_back(SdpSimulcastAttribute::Version());
5044
0
  versions.back().choices.push_back("8");
5045
0
  versions.Serialize(os);
5046
0
  ASSERT_EQ("pt=8", os.str());
5047
0
  os.str("");
5048
0
5049
0
  versions.type = SdpSimulcastAttribute::Versions::kRid;
5050
0
  versions.Serialize(os);
5051
0
  ASSERT_EQ("rid=8", os.str());
5052
0
  os.str("");
5053
0
5054
0
  versions.push_back(SdpSimulcastAttribute::Version());
5055
0
  versions.Serialize(os);
5056
0
  ASSERT_EQ("rid=8", os.str());
5057
0
  os.str("");
5058
0
5059
0
  versions.back().choices.push_back("9");
5060
0
  versions.Serialize(os);
5061
0
  ASSERT_EQ("rid=8;9", os.str());
5062
0
  os.str("");
5063
0
5064
0
  versions.push_back(SdpSimulcastAttribute::Version());
5065
0
  versions.back().choices.push_back("0");
5066
0
  versions.Serialize(os);
5067
0
  ASSERT_EQ("rid=8;9;0", os.str());
5068
0
  os.str("");
5069
0
}
5070
5071
static SdpSimulcastAttribute::Versions
5072
ParseSimulcastVersions(const std::string& input)
5073
0
{
5074
0
  std::istringstream is(input + " ");
5075
0
  std::string error;
5076
0
  SdpSimulcastAttribute::Versions list;
5077
0
  EXPECT_TRUE(list.Parse(is, &error)) << error;
5078
0
  EXPECT_EQ(' ', is.get());
5079
0
  EXPECT_EQ(EOF, is.get());
5080
0
  return list;
5081
0
}
5082
5083
TEST(NewSdpTestNoFixture, CheckSimulcastVersionsValidParse)
5084
0
{
5085
0
  {
5086
0
    SdpSimulcastAttribute::Versions versions(
5087
0
        ParseSimulcastVersions("pt=8"));
5088
0
    ASSERT_EQ(1U, versions.size());
5089
0
    ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt, versions.type);
5090
0
    ASSERT_EQ(1U, versions[0].choices.size());
5091
0
    ASSERT_EQ("8", versions[0].choices[0]);
5092
0
  }
5093
0
5094
0
  {
5095
0
    SdpSimulcastAttribute::Versions versions(
5096
0
        ParseSimulcastVersions("rid=8"));
5097
0
    ASSERT_EQ(1U, versions.size());
5098
0
    ASSERT_EQ(SdpSimulcastAttribute::Versions::kRid, versions.type);
5099
0
    ASSERT_EQ(1U, versions[0].choices.size());
5100
0
    ASSERT_EQ("8", versions[0].choices[0]);
5101
0
  }
5102
0
5103
0
  {
5104
0
    SdpSimulcastAttribute::Versions versions(
5105
0
        ParseSimulcastVersions("pt=8,9"));
5106
0
    ASSERT_EQ(1U, versions.size());
5107
0
    ASSERT_EQ(2U, versions[0].choices.size());
5108
0
    ASSERT_EQ("8", versions[0].choices[0]);
5109
0
    ASSERT_EQ("9", versions[0].choices[1]);
5110
0
  }
5111
0
5112
0
  {
5113
0
    SdpSimulcastAttribute::Versions versions(
5114
0
        ParseSimulcastVersions("pt=8,9;10"));
5115
0
    ASSERT_EQ(2U, versions.size());
5116
0
    ASSERT_EQ(2U, versions[0].choices.size());
5117
0
    ASSERT_EQ("8", versions[0].choices[0]);
5118
0
    ASSERT_EQ("9", versions[0].choices[1]);
5119
0
    ASSERT_EQ(1U, versions[1].choices.size());
5120
0
    ASSERT_EQ("10", versions[1].choices[0]);
5121
0
  }
5122
0
}
5123
5124
TEST(NewSdpTestNoFixture, CheckSimulcastVersionsInvalidParse)
5125
0
{
5126
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("", 0);
5127
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("x", 1);
5128
0
  ParseInvalid<SdpSimulcastAttribute::Versions>(";", 1);
5129
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("8", 1);
5130
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("foo=", 4);
5131
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("foo=8", 4);
5132
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("pt=9999", 7);
5133
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("pt=-1", 5);
5134
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("pt=x", 4);
5135
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("pt=8;", 5);
5136
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("pt=8;x", 6);
5137
0
  ParseInvalid<SdpSimulcastAttribute::Versions>("pt=8;;", 5);
5138
0
}
5139
5140
TEST(NewSdpTestNoFixture, CheckSimulcastSerialize)
5141
0
{
5142
0
  std::ostringstream os;
5143
0
5144
0
  SdpSimulcastAttribute simulcast;
5145
0
  simulcast.recvVersions.type = SdpSimulcastAttribute::Versions::kRid;
5146
0
  simulcast.recvVersions.push_back(SdpSimulcastAttribute::Version());
5147
0
  simulcast.recvVersions.back().choices.push_back("8");
5148
0
  simulcast.Serialize(os);
5149
0
  ASSERT_EQ("a=simulcast: recv rid=8" CRLF, os.str());
5150
0
  os.str("");
5151
0
5152
0
  simulcast.sendVersions.type = SdpSimulcastAttribute::Versions::kRid;
5153
0
  simulcast.sendVersions.push_back(SdpSimulcastAttribute::Version());
5154
0
  simulcast.sendVersions.back().choices.push_back("9");
5155
0
  simulcast.Serialize(os);
5156
0
  ASSERT_EQ("a=simulcast: send rid=9 recv rid=8" CRLF, os.str());
5157
0
}
5158
5159
static SdpSimulcastAttribute
5160
ParseSimulcast(const std::string& input)
5161
0
{
5162
0
  std::istringstream is(input);
5163
0
  std::string error;
5164
0
  SdpSimulcastAttribute simulcast;
5165
0
  EXPECT_TRUE(simulcast.Parse(is, &error)) << error;
5166
0
  EXPECT_TRUE(is.eof());
5167
0
  return simulcast;
5168
0
}
5169
5170
TEST(NewSdpTestNoFixture, CheckSimulcastValidParse)
5171
0
{
5172
0
  {
5173
0
    SdpSimulcastAttribute simulcast(ParseSimulcast(" send pt=8"));
5174
0
    ASSERT_EQ(1U, simulcast.sendVersions.size());
5175
0
    ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
5176
0
              simulcast.sendVersions.type);
5177
0
    ASSERT_EQ(1U, simulcast.sendVersions[0].choices.size());
5178
0
    ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
5179
0
    ASSERT_EQ(0U, simulcast.recvVersions.size());
5180
0
  }
5181
0
5182
0
  {
5183
0
    SdpSimulcastAttribute simulcast(ParseSimulcast(" SEND pt=8"));
5184
0
    ASSERT_EQ(1U, simulcast.sendVersions.size());
5185
0
    ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
5186
0
              simulcast.sendVersions.type);
5187
0
    ASSERT_EQ(1U, simulcast.sendVersions[0].choices.size());
5188
0
    ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
5189
0
    ASSERT_EQ(0U, simulcast.recvVersions.size());
5190
0
  }
5191
0
5192
0
  {
5193
0
    SdpSimulcastAttribute simulcast(ParseSimulcast(" recv pt=8"));
5194
0
    ASSERT_EQ(1U, simulcast.recvVersions.size());
5195
0
    ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
5196
0
              simulcast.recvVersions.type);
5197
0
    ASSERT_EQ(1U, simulcast.recvVersions[0].choices.size());
5198
0
    ASSERT_EQ("8", simulcast.recvVersions[0].choices[0]);
5199
0
    ASSERT_EQ(0U, simulcast.sendVersions.size());
5200
0
  }
5201
0
5202
0
  {
5203
0
    SdpSimulcastAttribute simulcast(
5204
0
        ParseSimulcast(
5205
0
          " send pt=8,9;101;97,98 recv pt=101,120;97"));
5206
0
    ASSERT_EQ(3U, simulcast.sendVersions.size());
5207
0
    ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
5208
0
              simulcast.sendVersions.type);
5209
0
    ASSERT_EQ(2U, simulcast.sendVersions[0].choices.size());
5210
0
    ASSERT_EQ("8", simulcast.sendVersions[0].choices[0]);
5211
0
    ASSERT_EQ("9", simulcast.sendVersions[0].choices[1]);
5212
0
    ASSERT_EQ(1U, simulcast.sendVersions[1].choices.size());
5213
0
    ASSERT_EQ("101", simulcast.sendVersions[1].choices[0]);
5214
0
    ASSERT_EQ(2U, simulcast.sendVersions[2].choices.size());
5215
0
    ASSERT_EQ("97", simulcast.sendVersions[2].choices[0]);
5216
0
    ASSERT_EQ("98", simulcast.sendVersions[2].choices[1]);
5217
0
5218
0
    ASSERT_EQ(2U, simulcast.recvVersions.size());
5219
0
    ASSERT_EQ(SdpSimulcastAttribute::Versions::kPt,
5220
0
              simulcast.recvVersions.type);
5221
0
    ASSERT_EQ(2U, simulcast.recvVersions[0].choices.size());
5222
0
    ASSERT_EQ("101", simulcast.recvVersions[0].choices[0]);
5223
0
    ASSERT_EQ("120", simulcast.recvVersions[0].choices[1]);
5224
0
    ASSERT_EQ(1U, simulcast.recvVersions[1].choices.size());
5225
0
    ASSERT_EQ("97", simulcast.recvVersions[1].choices[0]);
5226
0
  }
5227
0
}
5228
5229
TEST(NewSdpTestNoFixture, CheckSimulcastInvalidParse)
5230
0
{
5231
0
  ParseInvalid<SdpSimulcastAttribute>("", 0);
5232
0
  ParseInvalid<SdpSimulcastAttribute>(" ", 1);
5233
0
  ParseInvalid<SdpSimulcastAttribute>("vcer ", 4);
5234
0
  ParseInvalid<SdpSimulcastAttribute>(" send x", 7);
5235
0
  ParseInvalid<SdpSimulcastAttribute>(" recv x", 7);
5236
0
  ParseInvalid<SdpSimulcastAttribute>(" send pt=8 send ", 15);
5237
0
  ParseInvalid<SdpSimulcastAttribute>(" recv pt=8 recv ", 15);
5238
0
}
5239
5240
static SdpRidAttributeList::Rid
5241
ParseRid(const std::string& input)
5242
0
{
5243
0
  std::istringstream is(input);
5244
0
  std::string error;
5245
0
  SdpRidAttributeList::Rid rid;
5246
0
  EXPECT_TRUE(rid.Parse(is, &error)) << error;
5247
0
  EXPECT_TRUE(is.eof());
5248
0
  return rid;
5249
0
}
5250
5251
TEST(NewSdpTestNoFixture, CheckRidValidParse)
5252
0
{
5253
0
  {
5254
0
    SdpRidAttributeList::Rid rid(ParseRid("1 send"));
5255
0
    ASSERT_EQ("1", rid.id);
5256
0
    ASSERT_EQ(sdp::kSend, rid.direction);
5257
0
    ASSERT_EQ(0U, rid.formats.size());
5258
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5259
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5260
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5261
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5262
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5263
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5264
0
    ASSERT_EQ(0U, rid.dependIds.size());
5265
0
  }
5266
0
5267
0
  {
5268
0
    SdpRidAttributeList::Rid rid(ParseRid("1 send pt=96;max-width=800"));
5269
0
    ASSERT_EQ("1", rid.id);
5270
0
    ASSERT_EQ(sdp::kSend, rid.direction);
5271
0
    ASSERT_EQ(1U, rid.formats.size());
5272
0
    ASSERT_EQ(96U, rid.formats[0]);
5273
0
    ASSERT_EQ(800U, rid.constraints.maxWidth);
5274
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5275
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5276
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5277
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5278
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5279
0
    ASSERT_EQ(0U, rid.dependIds.size());
5280
0
  }
5281
0
5282
0
  {
5283
0
    SdpRidAttributeList::Rid rid(ParseRid("1 send pt=96,97,98;max-width=800"));
5284
0
    ASSERT_EQ("1", rid.id);
5285
0
    ASSERT_EQ(sdp::kSend, rid.direction);
5286
0
    ASSERT_EQ(3U, rid.formats.size());
5287
0
    ASSERT_EQ(96U, rid.formats[0]);
5288
0
    ASSERT_EQ(97U, rid.formats[1]);
5289
0
    ASSERT_EQ(98U, rid.formats[2]);
5290
0
    ASSERT_EQ(800U, rid.constraints.maxWidth);
5291
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5292
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5293
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5294
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5295
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5296
0
    ASSERT_EQ(0U, rid.dependIds.size());
5297
0
  }
5298
0
5299
0
  {
5300
0
    SdpRidAttributeList::Rid rid(
5301
0
        ParseRid("0123456789az-_ recv max-width=800"));
5302
0
    ASSERT_EQ("0123456789az-_", rid.id);
5303
0
    ASSERT_EQ(sdp::kRecv, rid.direction);
5304
0
    ASSERT_EQ(0U, rid.formats.size());
5305
0
    ASSERT_EQ(800U, rid.constraints.maxWidth);
5306
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5307
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5308
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5309
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5310
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5311
0
    ASSERT_EQ(0U, rid.dependIds.size());
5312
0
  }
5313
0
5314
0
  {
5315
0
    SdpRidAttributeList::Rid rid(
5316
0
        ParseRid("foo send"));
5317
0
    ASSERT_EQ(0U, rid.formats.size());
5318
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5319
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5320
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5321
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5322
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5323
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5324
0
    ASSERT_EQ(0U, rid.dependIds.size());
5325
0
  }
5326
0
5327
0
  {
5328
0
    SdpRidAttributeList::Rid rid(
5329
0
        ParseRid("foo send pt=96"));
5330
0
    ASSERT_EQ(1U, rid.formats.size());
5331
0
    ASSERT_EQ(96U, rid.formats[0]);
5332
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5333
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5334
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5335
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5336
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5337
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5338
0
    ASSERT_EQ(0U, rid.dependIds.size());
5339
0
  }
5340
0
5341
0
  // This is not technically permitted by the BNF, but the parse code is simpler
5342
0
  // if we allow it. If we decide to stop allowing this, this will need to be
5343
0
  // converted to an invalid parse test-case.
5344
0
  {
5345
0
    SdpRidAttributeList::Rid rid(
5346
0
        ParseRid("foo send max-br=30000;pt=96"));
5347
0
    ASSERT_EQ(1U, rid.formats.size());
5348
0
    ASSERT_EQ(96U, rid.formats[0]);
5349
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5350
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5351
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5352
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5353
0
    ASSERT_EQ(30000U, rid.constraints.maxBr);
5354
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5355
0
    ASSERT_EQ(0U, rid.dependIds.size());
5356
0
  }
5357
0
5358
0
  {
5359
0
    SdpRidAttributeList::Rid rid(
5360
0
        ParseRid("foo send pt=96,97,98"));
5361
0
    ASSERT_EQ(3U, rid.formats.size());
5362
0
    ASSERT_EQ(96U, rid.formats[0]);
5363
0
    ASSERT_EQ(97U, rid.formats[1]);
5364
0
    ASSERT_EQ(98U, rid.formats[2]);
5365
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5366
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5367
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5368
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5369
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5370
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5371
0
    ASSERT_EQ(0U, rid.dependIds.size());
5372
0
  }
5373
0
5374
0
  {
5375
0
    SdpRidAttributeList::Rid rid(
5376
0
        ParseRid("foo send max-width=800"));
5377
0
    ASSERT_EQ(0U, rid.formats.size());
5378
0
    ASSERT_EQ(800U, rid.constraints.maxWidth);
5379
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5380
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5381
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5382
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5383
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5384
0
    ASSERT_EQ(0U, rid.dependIds.size());
5385
0
  }
5386
0
5387
0
  {
5388
0
    SdpRidAttributeList::Rid rid(
5389
0
        ParseRid("foo send max-height=640"));
5390
0
    ASSERT_EQ(0U, rid.formats.size());
5391
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5392
0
    ASSERT_EQ(640U, rid.constraints.maxHeight);
5393
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5394
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5395
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5396
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5397
0
    ASSERT_EQ(0U, rid.dependIds.size());
5398
0
  }
5399
0
5400
0
  {
5401
0
    SdpRidAttributeList::Rid rid(
5402
0
        ParseRid("foo send max-fps=30"));
5403
0
    ASSERT_EQ(0U, rid.formats.size());
5404
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5405
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5406
0
    ASSERT_EQ(30U, rid.constraints.maxFps);
5407
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5408
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5409
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5410
0
    ASSERT_EQ(0U, rid.dependIds.size());
5411
0
  }
5412
0
5413
0
  {
5414
0
    SdpRidAttributeList::Rid rid(
5415
0
        ParseRid("foo send max-fs=3600"));
5416
0
    ASSERT_EQ(0U, rid.formats.size());
5417
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5418
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5419
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5420
0
    ASSERT_EQ(3600U, rid.constraints.maxFs);
5421
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5422
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5423
0
    ASSERT_EQ(0U, rid.dependIds.size());
5424
0
  }
5425
0
5426
0
  {
5427
0
    SdpRidAttributeList::Rid rid(
5428
0
        ParseRid("foo send max-br=30000"));
5429
0
    ASSERT_EQ(0U, rid.formats.size());
5430
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5431
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5432
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5433
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5434
0
    ASSERT_EQ(30000U, rid.constraints.maxBr);
5435
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5436
0
    ASSERT_EQ(0U, rid.dependIds.size());
5437
0
  }
5438
0
5439
0
  {
5440
0
    SdpRidAttributeList::Rid rid(
5441
0
        ParseRid("foo send max-pps=9216000"));
5442
0
    ASSERT_EQ(0U, rid.formats.size());
5443
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5444
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5445
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5446
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5447
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5448
0
    ASSERT_EQ(9216000U, rid.constraints.maxPps);
5449
0
    ASSERT_EQ(0U, rid.dependIds.size());
5450
0
  }
5451
0
5452
0
  {
5453
0
    SdpRidAttributeList::Rid rid(
5454
0
        ParseRid("foo send depend=foo"));
5455
0
    ASSERT_EQ(0U, rid.formats.size());
5456
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5457
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5458
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5459
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5460
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5461
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5462
0
    ASSERT_EQ(1U, rid.dependIds.size());
5463
0
    ASSERT_EQ("foo", rid.dependIds[0]);
5464
0
  }
5465
0
5466
0
  {
5467
0
    SdpRidAttributeList::Rid rid(
5468
0
        ParseRid("foo send max-foo=20"));
5469
0
    ASSERT_EQ(0U, rid.formats.size());
5470
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5471
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5472
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5473
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5474
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5475
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5476
0
    ASSERT_EQ(0U, rid.dependIds.size());
5477
0
  }
5478
0
5479
0
  {
5480
0
    SdpRidAttributeList::Rid rid(
5481
0
        ParseRid("foo send depend=foo,bar"));
5482
0
    ASSERT_EQ(0U, rid.formats.size());
5483
0
    ASSERT_EQ(0U, rid.constraints.maxWidth);
5484
0
    ASSERT_EQ(0U, rid.constraints.maxHeight);
5485
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5486
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5487
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5488
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5489
0
    ASSERT_EQ(2U, rid.dependIds.size());
5490
0
    ASSERT_EQ("foo", rid.dependIds[0]);
5491
0
    ASSERT_EQ("bar", rid.dependIds[1]);
5492
0
  }
5493
0
5494
0
  {
5495
0
    SdpRidAttributeList::Rid rid(
5496
0
        ParseRid("foo send max-width=800;max-height=600"));
5497
0
    ASSERT_EQ(0U, rid.formats.size());
5498
0
    ASSERT_EQ(800U, rid.constraints.maxWidth);
5499
0
    ASSERT_EQ(600U, rid.constraints.maxHeight);
5500
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5501
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5502
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5503
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5504
0
    ASSERT_EQ(0U, rid.dependIds.size());
5505
0
  }
5506
0
5507
0
  {
5508
0
    SdpRidAttributeList::Rid rid(
5509
0
        ParseRid("foo send pt=96,97;max-width=800;max-height=600"));
5510
0
    ASSERT_EQ(2U, rid.formats.size());
5511
0
    ASSERT_EQ(96U, rid.formats[0]);
5512
0
    ASSERT_EQ(97U, rid.formats[1]);
5513
0
    ASSERT_EQ(800U, rid.constraints.maxWidth);
5514
0
    ASSERT_EQ(600U, rid.constraints.maxHeight);
5515
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5516
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5517
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5518
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5519
0
    ASSERT_EQ(0U, rid.dependIds.size());
5520
0
  }
5521
0
5522
0
  {
5523
0
    SdpRidAttributeList::Rid rid(
5524
0
        ParseRid("foo send depend=foo,bar;max-width=800;max-height=600"));
5525
0
    ASSERT_EQ(0U, rid.formats.size());
5526
0
    ASSERT_EQ(800U, rid.constraints.maxWidth);
5527
0
    ASSERT_EQ(600U, rid.constraints.maxHeight);
5528
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5529
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5530
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5531
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5532
0
    ASSERT_EQ(2U, rid.dependIds.size());
5533
0
    ASSERT_EQ("foo", rid.dependIds[0]);
5534
0
    ASSERT_EQ("bar", rid.dependIds[1]);
5535
0
  }
5536
0
5537
0
  {
5538
0
    SdpRidAttributeList::Rid rid(
5539
0
        ParseRid("foo send max-foo=20;max-width=800;max-height=600"));
5540
0
    ASSERT_EQ(0U, rid.formats.size());
5541
0
    ASSERT_EQ(800U, rid.constraints.maxWidth);
5542
0
    ASSERT_EQ(600U, rid.constraints.maxHeight);
5543
0
    ASSERT_EQ(0U, rid.constraints.maxFps);
5544
0
    ASSERT_EQ(0U, rid.constraints.maxFs);
5545
0
    ASSERT_EQ(0U, rid.constraints.maxBr);
5546
0
    ASSERT_EQ(0U, rid.constraints.maxPps);
5547
0
    ASSERT_EQ(0U, rid.dependIds.size());
5548
0
  }
5549
0
}
5550
5551
TEST(NewSdpTestNoFixture, CheckRidInvalidParse)
5552
0
{
5553
0
  ParseInvalid<SdpRidAttributeList::Rid>("", 0);
5554
0
  ParseInvalid<SdpRidAttributeList::Rid>(" ", 0);
5555
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo", 3);
5556
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo ", 4);
5557
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo  ", 5);
5558
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo bar", 7);
5559
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo recv ", 9);
5560
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo recv pt=", 12);
5561
0
  ParseInvalid<SdpRidAttributeList::Rid>(" ", 0);
5562
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send pt", 11);
5563
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send pt=", 12);
5564
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send pt=x", 12);
5565
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send pt=-1", 12);
5566
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send pt=96,", 15);
5567
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send pt=196", 15);
5568
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send max-width", 18);
5569
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send max-width=", 19);
5570
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send max-width=x", 19);
5571
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send max-width=-1", 19);
5572
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send max-width=800;", 23);
5573
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send max-width=800; ", 24);
5574
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send depend=",16);
5575
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send depend=,", 16);
5576
0
  ParseInvalid<SdpRidAttributeList::Rid>("foo send depend=1,", 18);
5577
0
}
5578
5579
TEST(NewSdpTestNoFixture, CheckRidSerialize)
5580
0
{
5581
0
  {
5582
0
    SdpRidAttributeList::Rid rid;
5583
0
    rid.id = "foo";
5584
0
    rid.direction = sdp::kSend;
5585
0
    std::ostringstream os;
5586
0
    rid.Serialize(os);
5587
0
    ASSERT_EQ("foo send", os.str());
5588
0
  }
5589
0
5590
0
  {
5591
0
    SdpRidAttributeList::Rid rid;
5592
0
    rid.id = "foo";
5593
0
    rid.direction = sdp::kSend;
5594
0
    std::ostringstream os;
5595
0
    rid.Serialize(os);
5596
0
    ASSERT_EQ("foo send", os.str());
5597
0
  }
5598
0
5599
0
  {
5600
0
    SdpRidAttributeList::Rid rid;
5601
0
    rid.id = "foo";
5602
0
    rid.direction = sdp::kSend;
5603
0
    rid.formats.push_back(96);
5604
0
    std::ostringstream os;
5605
0
    rid.Serialize(os);
5606
0
    ASSERT_EQ("foo send pt=96", os.str());
5607
0
  }
5608
0
5609
0
  {
5610
0
    SdpRidAttributeList::Rid rid;
5611
0
    rid.id = "foo";
5612
0
    rid.direction = sdp::kSend;
5613
0
    rid.formats.push_back(96);
5614
0
    rid.formats.push_back(97);
5615
0
    std::ostringstream os;
5616
0
    rid.Serialize(os);
5617
0
    ASSERT_EQ("foo send pt=96,97", os.str());
5618
0
  }
5619
0
5620
0
  {
5621
0
    SdpRidAttributeList::Rid rid;
5622
0
    rid.id = "foo";
5623
0
    rid.direction = sdp::kSend;
5624
0
    rid.constraints.maxWidth = 800;
5625
0
    std::ostringstream os;
5626
0
    rid.Serialize(os);
5627
0
    ASSERT_EQ("foo send max-width=800", os.str());
5628
0
  }
5629
0
5630
0
  {
5631
0
    SdpRidAttributeList::Rid rid;
5632
0
    rid.id = "foo";
5633
0
    rid.direction = sdp::kSend;
5634
0
    rid.constraints.maxHeight = 600;
5635
0
    std::ostringstream os;
5636
0
    rid.Serialize(os);
5637
0
    ASSERT_EQ("foo send max-height=600", os.str());
5638
0
  }
5639
0
5640
0
  {
5641
0
    SdpRidAttributeList::Rid rid;
5642
0
    rid.id = "foo";
5643
0
    rid.direction = sdp::kSend;
5644
0
    rid.constraints.maxFps = 30;
5645
0
    std::ostringstream os;
5646
0
    rid.Serialize(os);
5647
0
    ASSERT_EQ("foo send max-fps=30", os.str());
5648
0
  }
5649
0
5650
0
  {
5651
0
    SdpRidAttributeList::Rid rid;
5652
0
    rid.id = "foo";
5653
0
    rid.direction = sdp::kSend;
5654
0
    rid.constraints.maxFs = 3600;
5655
0
    std::ostringstream os;
5656
0
    rid.Serialize(os);
5657
0
    ASSERT_EQ("foo send max-fs=3600", os.str());
5658
0
  }
5659
0
5660
0
  {
5661
0
    SdpRidAttributeList::Rid rid;
5662
0
    rid.id = "foo";
5663
0
    rid.direction = sdp::kSend;
5664
0
    rid.constraints.maxBr = 30000;
5665
0
    std::ostringstream os;
5666
0
    rid.Serialize(os);
5667
0
    ASSERT_EQ("foo send max-br=30000", os.str());
5668
0
  }
5669
0
5670
0
  {
5671
0
    SdpRidAttributeList::Rid rid;
5672
0
    rid.id = "foo";
5673
0
    rid.direction = sdp::kSend;
5674
0
    rid.constraints.maxPps = 9216000;
5675
0
    std::ostringstream os;
5676
0
    rid.Serialize(os);
5677
0
    ASSERT_EQ("foo send max-pps=9216000", os.str());
5678
0
  }
5679
0
5680
0
  {
5681
0
    SdpRidAttributeList::Rid rid;
5682
0
    rid.id = "foo";
5683
0
    rid.direction = sdp::kSend;
5684
0
    rid.dependIds.push_back("foo");
5685
0
    std::ostringstream os;
5686
0
    rid.Serialize(os);
5687
0
    ASSERT_EQ("foo send depend=foo", os.str());
5688
0
  }
5689
0
5690
0
  {
5691
0
    SdpRidAttributeList::Rid rid;
5692
0
    rid.id = "foo";
5693
0
    rid.direction = sdp::kSend;
5694
0
    rid.dependIds.push_back("foo");
5695
0
    rid.dependIds.push_back("bar");
5696
0
    std::ostringstream os;
5697
0
    rid.Serialize(os);
5698
0
    ASSERT_EQ("foo send depend=foo,bar", os.str());
5699
0
  }
5700
0
5701
0
  {
5702
0
    SdpRidAttributeList::Rid rid;
5703
0
    rid.id = "foo";
5704
0
    rid.direction = sdp::kSend;
5705
0
    rid.formats.push_back(96);
5706
0
    rid.constraints.maxBr = 30000;
5707
0
    std::ostringstream os;
5708
0
    rid.Serialize(os);
5709
0
    ASSERT_EQ("foo send pt=96;max-br=30000", os.str());
5710
0
  }
5711
0
}
5712
5713
TEST_F(SdpTest, hugeSdp)
5714
0
{
5715
0
  std::string offer =
5716
0
    "v=0\r\n"
5717
0
    "o=- 1109973417102828257 2 IN IP4 127.0.0.1\r\n"
5718
0
    "s=-\r\n"
5719
0
    "t=0 0\r\n"
5720
0
    "a=group:BUNDLE audio video\r\n"
5721
0
    "a=msid-semantic: WMS 1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP\r\n"
5722
0
    "m=audio 32952 UDP/TLS/RTP/SAVPF 111 103 104 0 8 107 106 105 13 126\r\n"
5723
0
    "c=IN IP4 128.64.32.16\r\n"
5724
0
    "a=rtcp:32952 IN IP4 128.64.32.16\r\n"
5725
0
    "a=candidate:77142221 1 udp 2113937151 192.168.137.1 54081 typ host generation 0\r\n"
5726
0
    "a=candidate:77142221 2 udp 2113937151 192.168.137.1 54081 typ host generation 0\r\n"
5727
0
    "a=candidate:983072742 1 udp 2113937151 172.22.0.56 54082 typ host generation 0\r\n"
5728
0
    "a=candidate:983072742 2 udp 2113937151 172.22.0.56 54082 typ host generation 0\r\n"
5729
0
    "a=candidate:2245074553 1 udp 1845501695 32.64.128.1 62397 typ srflx raddr 192.168.137.1 rport 54081 generation 0\r\n"
5730
0
    "a=candidate:2245074553 2 udp 1845501695 32.64.128.1 62397 typ srflx raddr 192.168.137.1 rport 54081 generation 0\r\n"
5731
0
    "a=candidate:2479353907 1 udp 1845501695 32.64.128.1 54082 typ srflx raddr 172.22.0.56 rport 54082 generation 0\r\n"
5732
0
    "a=candidate:2479353907 2 udp 1845501695 32.64.128.1 54082 typ srflx raddr 172.22.0.56 rport 54082 generation 0\r\n"
5733
0
    "a=candidate:1243276349 1 tcp 1509957375 192.168.137.1 0 typ host generation 0\r\n"
5734
0
    "a=candidate:1243276349 2 tcp 1509957375 192.168.137.1 0 typ host generation 0\r\n"
5735
0
    "a=candidate:1947960086 1 tcp 1509957375 172.22.0.56 0 typ host generation 0\r\n"
5736
0
    "a=candidate:1947960086 2 tcp 1509957375 172.22.0.56 0 typ host generation 0\r\n"
5737
0
    "a=candidate:1808221584 1 udp 33562367 128.64.32.16 32952 typ relay raddr 32.64.128.1 rport 62398 generation 0\r\n"
5738
0
    "a=candidate:1808221584 2 udp 33562367 128.64.32.16 32952 typ relay raddr 32.64.128.1 rport 62398 generation 0\r\n"
5739
0
    "a=candidate:507872740 1 udp 33562367 128.64.32.16 40975 typ relay raddr 32.64.128.1 rport 54085 generation 0\r\n"
5740
0
    "a=candidate:507872740 2 udp 33562367 128.64.32.16 40975 typ relay raddr 32.64.128.1 rport 54085 generation 0\r\n"
5741
0
    "a=ice-ufrag:xQuJwjX3V3eMA81k\r\n"
5742
0
    "a=ice-pwd:ZUiRmjS2GDhG140p73dAsSVP\r\n"
5743
0
    "a=ice-options:google-ice\r\n"
5744
0
    "a=fingerprint:sha-256 59:4A:8B:73:A7:73:53:71:88:D7:4D:58:28:0C:79:72:31:29:9B:05:37:DD:58:43:C2:D4:85:A2:B3:66:38:7A\r\n"
5745
0
    "a=setup:active\r\n"
5746
0
    "a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\n"
5747
0
    "a=sendrecv\r\n"
5748
0
    "a=mid:audio\r\n"
5749
0
    "a=rtcp-mux\r\n"
5750
0
    "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:/U44g3ULdtapeiSg+T3n6dDLBKIjpOhb/NXAL/2b\r\n"
5751
0
    "a=rtpmap:111 opus/48000/2\r\n"
5752
0
    "a=fmtp:111 minptime=10\r\n"
5753
0
    "a=rtpmap:103 ISAC/16000\r\n"
5754
0
    "a=rtpmap:104 ISAC/32000\r\n"
5755
0
    "a=rtpmap:0 PCMU/8000\r\n"
5756
0
    "a=rtpmap:8 PCMA/8000\r\n"
5757
0
    "a=rtpmap:107 CN/48000\r\n"
5758
0
    "a=rtpmap:106 CN/32000\r\n"
5759
0
    "a=rtpmap:105 CN/16000\r\n"
5760
0
    "a=rtpmap:13 CN/8000\r\n"
5761
0
    "a=rtpmap:126 telephone-event/8000\r\n"
5762
0
    "a=maxptime:60\r\n"
5763
0
    "a=ssrc:2271517329 cname:mKDNt7SQf6pwDlIn\r\n"
5764
0
    "a=ssrc:2271517329 msid:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP 1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPa0\r\n"
5765
0
    "a=ssrc:2271517329 mslabel:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP\r\n"
5766
0
    "a=ssrc:2271517329 label:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPa0\r\n"
5767
0
    "m=video 32952 UDP/TLS/RTP/SAVPF 100 116 117\r\n"
5768
0
    "c=IN IP4 128.64.32.16\r\n"
5769
0
    "a=rtcp:32952 IN IP4 128.64.32.16\r\n"
5770
0
    "a=candidate:77142221 1 udp 2113937151 192.168.137.1 54081 typ host generation 0\r\n"
5771
0
    "a=candidate:77142221 2 udp 2113937151 192.168.137.1 54081 typ host generation 0\r\n"
5772
0
    "a=candidate:983072742 1 udp 2113937151 172.22.0.56 54082 typ host generation 0\r\n"
5773
0
    "a=candidate:983072742 2 udp 2113937151 172.22.0.56 54082 typ host generation 0\r\n"
5774
0
    "a=candidate:2245074553 1 udp 1845501695 32.64.128.1 62397 typ srflx raddr 192.168.137.1 rport 54081 generation 0\r\n"
5775
0
    "a=candidate:2245074553 2 udp 1845501695 32.64.128.1 62397 typ srflx raddr 192.168.137.1 rport 54081 generation 0\r\n"
5776
0
    "a=candidate:2479353907 1 udp 1845501695 32.64.128.1 54082 typ srflx raddr 172.22.0.56 rport 54082 generation 0\r\n"
5777
0
    "a=candidate:2479353907 2 udp 1845501695 32.64.128.1 54082 typ srflx raddr 172.22.0.56 rport 54082 generation 0\r\n"
5778
0
    "a=candidate:1243276349 1 tcp 1509957375 192.168.137.1 0 typ host generation 0\r\n"
5779
0
    "a=candidate:1243276349 2 tcp 1509957375 192.168.137.1 0 typ host generation 0\r\n"
5780
0
    "a=candidate:1947960086 1 tcp 1509957375 172.22.0.56 0 typ host generation 0\r\n"
5781
0
    "a=candidate:1947960086 2 tcp 1509957375 172.22.0.56 0 typ host generation 0\r\n"
5782
0
    "a=candidate:1808221584 1 udp 33562367 128.64.32.16 32952 typ relay raddr 32.64.128.1 rport 62398 generation 0\r\n"
5783
0
    "a=candidate:1808221584 2 udp 33562367 128.64.32.16 32952 typ relay raddr 32.64.128.1 rport 62398 generation 0\r\n"
5784
0
    "a=candidate:507872740 1 udp 33562367 128.64.32.16 40975 typ relay raddr 32.64.128.1 rport 54085 generation 0\r\n"
5785
0
    "a=candidate:507872740 2 udp 33562367 128.64.32.16 40975 typ relay raddr 32.64.128.1 rport 54085 generation 0\r\n"
5786
0
    "a=ice-ufrag:xQuJwjX3V3eMA81k\r\n"
5787
0
    "a=ice-pwd:ZUiRmjS2GDhG140p73dAsSVP\r\n"
5788
0
    "a=ice-options:google-ice\r\n"
5789
0
    "a=fingerprint:sha-256 59:4A:8B:73:A7:73:53:71:88:D7:4D:58:28:0C:79:72:31:29:9B:05:37:DD:58:43:C2:D4:85:A2:B3:66:38:7A\r\n"
5790
0
    "a=setup:active\r\n"
5791
0
    "a=extmap:2 urn:ietf:params:rtp-hdrext:toffset\r\n"
5792
0
    "a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\n"
5793
0
    "a=sendrecv\r\n"
5794
0
    "a=mid:video\r\n"
5795
0
    "a=rtcp-mux\r\n"
5796
0
    "a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:/U44g3ULdtapeiSg+T3n6dDLBKIjpOhb/NXAL/2b\r\n"
5797
0
    "a=rtpmap:100 VP8/90000\r\n"
5798
0
    "a=rtcp-fb:100 ccm fir\r\n"
5799
0
    "a=rtcp-fb:100 nack\r\n"
5800
0
    "a=rtcp-fb:100 goog-remb\r\n"
5801
0
    "a=rtpmap:116 red/90000\r\n"
5802
0
    "a=rtpmap:117 ulpfec/90000\r\n"
5803
0
    "a=ssrc:54724160 cname:mKDNt7SQf6pwDlIn\r\n"
5804
0
    "a=ssrc:54724160 msid:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP 1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPv0\r\n"
5805
0
    "a=ssrc:54724160 mslabel:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIP\r\n"
5806
0
    "a=ssrc:54724160 label:1PBxet5BYh0oYodwsvNM4k6KiO2eWCX40VIPv0\r\n";
5807
0
5808
0
  ParseSdp(offer);
5809
0
}
5810
} // End namespace test.