blob: 4d15882d1e67bc0b8b81a60ec104976643a5c0dd [file] [log] [blame]
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001/* $Id$ */
2/*
Nanang Izzuddina62ffc92011-05-05 06:14:19 +00003 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
Benny Prijono32177c02008-06-20 22:44:47 +00004 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
Benny Prijono4ea0bf12006-02-02 19:16:07 +00005 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms oa the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 oa the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty oa
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy oa the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include <pjmedia/sdp.h>
21#include <pjmedia/sdp_neg.h>
22#include "test.h"
23
24
25#define THIS_FILE "sdp_neg_test.c"
26#define START_TEST 0
27
28enum session_type
29{
30 REMOTE_OFFER,
31 LOCAL_OFFER,
32};
33
34struct offer_answer
35{
36 enum session_type type; /* LOCAL_OFFER: REMOTE_OFFER: */
37 char *sdp1; /* local offer remote offer */
38 char *sdp2; /* remote answer initial local */
39 char *sdp3; /* local active media local answer */
40};
41
Nanang Izzuddin019e35b2009-04-15 17:54:46 +000042static struct test
Benny Prijono4ea0bf12006-02-02 19:16:07 +000043{
44 const char *title;
45 unsigned offer_answer_count;
46 struct offer_answer offer_answer[4];
47} test[] =
48{
49 /* test 0: */
50 {
51 /*********************************************************************
52 * RFC 3264 examples, section 10.1 (Alice's view)
53 *
54 * Difference from the example:
55 * - Bob's port number of the third media stream in the first answer
56 * is changed (make it different than Alice's)
57 * - in the second offer/answer exchange, Alice can't accept the
58 * additional line since she didn't specify the capability
59 * in the initial negotiator creation.
60 */
61
62 "RFC 3264 example 10.1 (Alice's view)",
63 2,
64 {
65 {
66 LOCAL_OFFER,
67 /* Alice sends offer: */
68 "v=0\r\n"
69 "o=alice 2890844526 2890844526 IN IP4 host.anywhere.com\r\n"
70 "s= \r\n"
71 "c=IN IP4 host.anywhere.com\r\n"
72 "t=0 0\r\n"
73 "m=audio 49170 RTP/AVP 0\r\n"
74 "a=rtpmap:0 PCMU/8000\r\n"
75 "m=video 51372 RTP/AVP 31\r\n"
76 "a=rtpmap:31 H261/90000\r\n"
77 "m=video 53000 RTP/AVP 32\r\n"
78 "a=rtpmap:32 MPV/90000\r\n",
79 /* Received Bob's answer: */
80 "v=0\r\n"
81 "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
82 "s= \r\n"
83 "c=IN IP4 host.example.com\r\n"
84 "t=0 0\r\n"
85 "m=audio 49920 RTP/AVP 0\r\n"
86 "a=rtpmap:0 PCMU/8000\r\n"
87 "m=video 0 RTP/AVP 31\r\n"
88 "m=video 53002 RTP/AVP 32\r\n"
89 "a=rtpmap:32 MPV/90000\r\n",
90 /* Alice's SDP now: */
91 "v=0\r\n"
92 "o=alice 2890844526 2890844526 IN IP4 host.anywhere.com\r\n"
93 "s= \r\n"
94 "c=IN IP4 host.anywhere.com\r\n"
95 "t=0 0\r\n"
96 "m=audio 49170 RTP/AVP 0\r\n"
97 "a=rtpmap:0 PCMU/8000\r\n"
98 "m=video 0 RTP/AVP 31\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +000099 //"a=rtpmap:31 H261/90000\r\n" /* <-- this is not necessary (port 0) */
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000100 "m=video 53000 RTP/AVP 32\r\n"
101 "a=rtpmap:32 MPV/90000\r\n"
102 },
103 {
104 REMOTE_OFFER,
105 /* Bob wants to change his local SDP
106 * (change local port for the first stream and add new stream)
107 * Received SDP from Bob:
108 */
109 "v=0\r\n"
110 "o=bob 2890844730 2890844731 IN IP4 host.example.com\r\n"
111 "s=-\r\n"
112 "c=IN IP4 host.example.com\r\n"
113 "t=0 0\r\n"
114 "m=audio 65422 RTP/AVP 0\r\n"
115 "a=rtpmap:0 PCMU/8000\r\n"
116 "m=video 0 RTP/AVP 31\r\n"
117 "m=video 53002 RTP/AVP 32\r\n"
118 "a=rtpmap:32 MPV/90000\r\n"
119 "m=audio 51434 RTP/AVP 110\r\n"
120 "a=rtpmap:110 telephone-events/8000\r\n"
121 "a=recvonly\r\n",
122 NULL,
123 /* Alice's SDP now */
124 "v=0\r\n"
125 "o=alice 2890844526 2890844527 IN IP4 host.anywhere.com\r\n"
126 "s= \r\n"
127 "c=IN IP4 host.anywhere.com\r\n"
128 "t=0 0\r\n"
129 "m=audio 49170 RTP/AVP 0\r\n"
130 "a=rtpmap:0 PCMU/8000\r\n"
131 "m=video 0 RTP/AVP 31\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +0000132 //"a=rtpmap:31 H261/90000\r\n" /* <-- this is not necessary (port 0) */
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000133 "m=video 53000 RTP/AVP 32\r\n"
134 "a=rtpmap:32 MPV/90000\r\n"
135 "m=audio 0 RTP/AVP 110\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +0000136 /* <-- the following attributes are not necessary (port 0) */
137 //"a=rtpmap:110 telephone-events/8000\r\n"
138 //"a=sendonly\r\n"
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000139 }
140 }
141 },
142
143 /* test 1: */
144 {
145 /*********************************************************************
146 * RFC 3264 examples, section 10.1. (Bob's view)
147 *
148 * Difference:
149 * - the SDP version in Bob's capability is changed to ver-1.
150 */
151
152 "RFC 3264 example 10.1 (Bob's view)",
153 2,
154 {
155 {
156 REMOTE_OFFER,
157 /* Remote offer from Alice: */
158 "v=0\r\n"
159 "o=alice 2890844526 2890844526 IN IP4 host.anywhere.com\r\n"
160 "s= \r\n"
161 "c=IN IP4 host.anywhere.com\r\n"
162 "t=0 0\r\n"
163 "m=audio 49170 RTP/AVP 0\r\n"
164 "a=rtpmap:0 PCMU/8000\r\n"
165 "m=video 51372 RTP/AVP 31\r\n"
166 "a=rtpmap:31 H261/90000\r\n"
167 "m=video 53000 RTP/AVP 32\r\n"
168 "a=rtpmap:32 MPV/90000\r\n",
169 /* Bob's capability: */
170 "v=0\r\n"
171 "o=bob 2890844730 2890844729 IN IP4 host.example.com\r\n"
172 "s= \r\n"
173 "c=IN IP4 host.example.com\r\n"
174 "t=0 0\r\n"
175 "m=audio 49920 RTP/AVP 0\r\n"
176 "a=rtpmap:0 PCMU/8000\r\n"
177 "m=video 0 RTP/AVP 31\r\n"
178 "m=video 53000 RTP/AVP 32\r\n"
179 "a=rtpmap:32 MPV/90000\r\n",
180 /* This's how Bob's answer should look like: */
181 "v=0\r\n"
182 "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
183 "s= \r\n"
184 "c=IN IP4 host.example.com\r\n"
185 "t=0 0\r\n"
186 "m=audio 49920 RTP/AVP 0\r\n"
187 "a=rtpmap:0 PCMU/8000\r\n"
188 "m=video 0 RTP/AVP 31\r\n"
189 "m=video 53000 RTP/AVP 32\r\n"
190 "a=rtpmap:32 MPV/90000\r\n"
191 },
192 {
193 LOCAL_OFFER,
194 /* Bob wants to change his local SDP
195 * (change local port for the first stream and add new stream)
196 */
197 "v=0\r\n"
198 "o=bob 2890844730 2890844731 IN IP4 host.example.com\r\n"
199 "s=-\r\n"
200 "c=IN IP4 host.example.com\r\n"
201 "t=0 0\r\n"
202 "m=audio 65422 RTP/AVP 0\r\n"
203 "a=rtpmap:0 PCMU/8000\r\n"
204 "m=video 0 RTP/AVP 31\r\n"
205 "m=video 53000 RTP/AVP 32\r\n"
206 "a=rtpmap:32 MPV/90000\r\n"
207 "m=audio 51434 RTP/AVP 110\r\n"
208 "a=rtpmap:110 telephone-events/8000\r\n"
209 "a=recvonly\r\n",
210 /* Got answer from Alice */
211 "v=0\r\n"
212 "o=alice 2890844526 2890844527 IN IP4 host.anywhere.com\r\n"
213 "s=-\r\n"
214 "c=IN IP4 host.anywhere.com\r\n"
215 "t=0 0\r\n"
216 "m=audio 49170 RTP/AVP 0\r\n"
217 "a=rtpmap:0 PCMU/8000\r\n"
218 "m=video 0 RTP/AVP 31\r\n"
219 "a=rtpmap:31 H261/90000\r\n"
220 "m=video 53000 RTP/AVP 32\r\n"
221 "a=rtpmap:32 MPV/90000\r\n"
222 "m=audio 53122 RTP/AVP 110\r\n"
223 "a=rtpmap:110 telephone-events/8000\r\n"
224 "a=sendonly\r\n",
225 /* This is how Bob's SDP should look like after negotiation */
226 "v=0\r\n"
227 "o=bob 2890844730 2890844731 IN IP4 host.example.com\r\n"
228 "s=-\r\n"
229 "c=IN IP4 host.example.com\r\n"
230 "t=0 0\r\n"
231 "m=audio 65422 RTP/AVP 0\r\n"
232 "a=rtpmap:0 PCMU/8000\r\n"
233 "m=video 0 RTP/AVP 31\r\n"
234 "m=video 53000 RTP/AVP 32\r\n"
235 "a=rtpmap:32 MPV/90000\r\n"
236 "m=audio 51434 RTP/AVP 110\r\n"
237 "a=rtpmap:110 telephone-events/8000\r\n"
238 "a=recvonly\r\n"
239 }
240 }
241 },
242
243 /* test 2: */
244 {
245 /*********************************************************************
246 * RFC 3264 examples, section 10.2.
247 * This is from Alice's point of view.
248 */
249
250 "RFC 3264 example 10.2 (Alice's view)",
251 2,
252 {
253 {
254 LOCAL_OFFER,
255 /* The initial offer from Alice to Bob indicates a single audio
256 * stream with the three audio codecs that are available in the
257 * DSP. The stream is marked as inactive,
258 */
259 "v=0\r\n"
260 "o=alice 2890844526 2890844526 IN IP4 host.anywhere.com\r\n"
261 "s=-\r\n"
262 "c=IN IP4 host.anywhere.com\r\n"
263 "t=0 0\r\n"
264 "m=audio 62986 RTP/AVP 0 4 18\r\n"
265 "a=rtpmap:0 PCMU/8000\r\n"
266 "a=rtpmap:4 G723/8000\r\n"
267 "a=rtpmap:18 G729/8000\r\n"
268 "a=inactive\r\n",
269 /* Bob can support dynamic switching between PCMU and G.723. So,
270 * he sends the following answer:
271 */
272 "v=0\r\n"
273 "o=bob 2890844730 2890844731 IN IP4 host.example.com\r\n"
274 "s=-\r\n"
275 "c=IN IP4 host.example.com\r\n"
276 "t=0 0\r\n"
277 "m=audio 54344 RTP/AVP 0 4\r\n"
278 "a=rtpmap:0 PCMU/8000\r\n"
279 "a=rtpmap:4 G723/8000\r\n"
280 "a=inactive\r\n",
281 /* This is how Alice's media should look like after negotiation */
282 "v=0\r\n"
283 "o=alice 2890844526 2890844526 IN IP4 host.anywhere.com\r\n"
284 "s=-\r\n"
285 "c=IN IP4 host.anywhere.com\r\n"
286 "t=0 0\r\n"
287 "m=audio 62986 RTP/AVP 0 4\r\n"
288 "a=rtpmap:0 PCMU/8000\r\n"
289 "a=rtpmap:4 G723/8000\r\n"
290 "a=inactive\r\n",
291 },
292 {
293 LOCAL_OFFER,
294 /* Alice sends an updated offer with a sendrecv stream: */
295 "v=0\r\n"
296 "o=alice 2890844526 2890844527 IN IP4 host.anywhere.com\r\n"
297 "s=-\r\n"
298 "c=IN IP4 host.anywhere.com\r\n"
299 "t=0 0\r\n"
300 "m=audio 62986 RTP/AVP 4\r\n"
301 "a=rtpmap:4 G723/8000\r\n"
302 "a=sendrecv\r\n",
303 /* Bob accepts the single codec: */
304 "v=0\r\n"
305 "o=bob 2890844730 2890844732 IN IP4 host.example.com\r\n"
306 "s= \r\n"
307 "c=IN IP4 host.example.com\r\n"
308 "t=0 0\r\n"
309 "m=audio 54344 RTP/AVP 4\r\n"
310 "a=rtpmap:4 G723/8000\r\n"
311 "a=sendrecv\r\n",
312 /* This is how Alice's media should look like after negotiation */
313 "v=0\r\n"
314 "o=alice 2890844526 2890844527 IN IP4 host.anywhere.com\r\n"
315 "s=-\r\n"
316 "c=IN IP4 host.anywhere.com\r\n"
317 "t=0 0\r\n"
318 "m=audio 62986 RTP/AVP 4\r\n"
319 "a=rtpmap:4 G723/8000\r\n"
320 "a=sendrecv\r\n"
321 }
322 }
323 },
324
Nanang Izzuddina5538ab2008-05-07 15:30:34 +0000325#if 0
326 // this test is commented, this causes error:
327 // No suitable codec for remote offer (PJMEDIA_SDPNEG_NOANSCODEC),
328 // since currently the negotiator always answer with one codec,
329 // PCMU in this case, while PCMU is not included in the second offer.
330
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000331 /* test 3: */
332 {
333 /*********************************************************************
334 * RFC 3264 examples, section 10.2.
335 * This is from Bob's point of view.
336 *
337 * Difference:
338 * - The SDP version number in Bob's initial capability is ver-1
339 */
340
341 "RFC 3264 example 10.2 (Bob's view)",
342 2,
343 {
344 {
345 REMOTE_OFFER,
346 /* Bob received offer from Alice:
347 */
348 "v=0\r\n"
349 "o=alice 2890844526 2890844526 IN IP4 host.anywhere.com\r\n"
350 "s=-\r\n"
351 "c=IN IP4 host.anywhere.com\r\n"
352 "t=0 0\r\n"
353 "m=audio 62986 RTP/AVP 0 4 18\r\n"
354 "a=rtpmap:0 PCMU/8000\r\n"
355 "a=rtpmap:4 G723/8000\r\n"
356 "a=rtpmap:18 G729/8000\r\n"
357 "a=inactive\r\n",
358 /* Bob's capability:
359 */
360 "v=0\r\n"
361 "o=bob 2890844730 2890844730 IN IP4 host.example.com\r\n"
362 "s=-\r\n"
363 "c=IN IP4 host.example.com\r\n"
364 "t=0 0\r\n"
365 "m=audio 54344 RTP/AVP 0 4\r\n"
366 "a=rtpmap:0 PCMU/8000\r\n"
367 "a=rtpmap:4 G723/8000\r\n"
368 "a=inactive\r\n",
369 /* This is how Bob's media should look like after negotiation */
370 "v=0\r\n"
371 "o=bob 2890844730 2890844731 IN IP4 host.example.com\r\n"
372 "s=-\r\n"
373 "c=IN IP4 host.example.com\r\n"
374 "t=0 0\r\n"
375 "m=audio 54344 RTP/AVP 0\r\n"
376 "a=rtpmap:0 PCMU/8000\r\n"
377 "a=inactive\r\n"
378 },
379 {
380 REMOTE_OFFER,
381 /* Received updated Alice's SDP: offer with a sendrecv stream: */
382 "v=0\r\n"
383 "o=alice 2890844526 2890844527 IN IP4 host.anywhere.com\r\n"
384 "s=-\r\n"
385 "c=IN IP4 host.anywhere.com\r\n"
386 "t=0 0\r\n"
387 "m=audio 62986 RTP/AVP 4\r\n"
388 "a=rtpmap:4 G723/8000\r\n"
389 "a=sendrecv\r\n",
390 /* Bob accepts the single codec: */
391 NULL,
392 /* This is how Bob's media should look like after negotiation */
393 "v=0\r\n"
394 "o=bob 2890844730 2890844732 IN IP4 host.example.com\r\n"
395 "s=-\r\n"
396 "c=IN IP4 host.example.com\r\n"
397 "t=0 0\r\n"
398 "m=audio 54344 RTP/AVP 4\r\n"
399 "a=rtpmap:4 G723/8000\r\n"
400 "a=sendrecv\r\n",
401 }
402 }
403 },
Nanang Izzuddina5538ab2008-05-07 15:30:34 +0000404#endif
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000405
406 /* test 4: */
407 {
408 /*********************************************************************
409 * RFC 4317 Sample 2.1: Audio and Video 1 (Alice's view)
410 *
411 * This common scenario shows a video and audio session in which
412 * multiple codecs are offered but only one is accepted. As a result of
413 * the exchange shown below, Alice and Bob may send only PCMU audio and
414 * MPV video. Note: Dynamic payload type 97 is used for iLBC codec
415 */
416 "RFC 4317 section 2.1: Audio and Video 1 (Alice's view)",
417 1,
418 {
419 {
420 LOCAL_OFFER,
421 /* Alice's local offer: */
422 "v=0\r\n"
423 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
424 "s=-\r\n"
425 "c=IN IP4 host.atlanta.example.com\r\n"
426 "t=0 0\r\n"
427 "m=audio 49170 RTP/AVP 0 8 97\r\n"
428 "a=rtpmap:0 PCMU/8000\r\n"
429 "a=rtpmap:8 PCMA/8000\r\n"
430 "a=rtpmap:97 iLBC/8000\r\n"
431 "m=video 51372 RTP/AVP 31 32\r\n"
432 "a=rtpmap:31 H261/90000\r\n"
433 "a=rtpmap:32 MPV/90000\r\n",
434 /* Received answer from Bob: */
435 "v=0\r\n"
436 "o=bob 2808844564 2808844564 IN IP4 host.biloxi.example.com\r\n"
437 "s=-\r\n"
438 "c=IN IP4 host.biloxi.example.com\r\n"
439 "t=0 0\r\n"
440 "m=audio 49174 RTP/AVP 0\r\n"
441 "a=rtpmap:0 PCMU/8000\r\n"
442 "m=video 49170 RTP/AVP 32\r\n"
443 "a=rtpmap:32 MPV/90000\r\n",
444 /* This is how Alice's media should look like now: */
445 "v=0\r\n"
446 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
447 "s=-\r\n"
448 "c=IN IP4 host.atlanta.example.com\r\n"
449 "t=0 0\r\n"
450 "m=audio 49170 RTP/AVP 0\r\n"
451 "a=rtpmap:0 PCMU/8000\r\n"
452 "m=video 51372 RTP/AVP 32\r\n"
453 "a=rtpmap:32 MPV/90000\r\n"
454 }
455 }
456 },
457
458 /* test 5: */
459 {
460 /*********************************************************************
461 * RFC 4317 Sample 2.1: Audio and Video 1 (Bob's view)
462 *
463 * This common scenario shows a video and audio session in which
464 * multiple codecs are offered but only one is accepted. As a result of
465 * the exchange shown below, Alice and Bob may send only PCMU audio and
466 * MPV video. Note: Dynamic payload type 97 is used for iLBC codec
467 *
468 * Difference:
469 * - Bob's initial capability version number
470 */
471 "RFC 4317 section 2.1: Audio and Video 1 (Bob's view)",
472 1,
473 {
474 {
475 REMOTE_OFFER,
476 /* Received Alice's local offer: */
477 "v=0\r\n"
478 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
479 "s=-\r\n"
480 "c=IN IP4 host.atlanta.example.com\r\n"
481 "t=0 0\r\n"
482 "m=audio 49170 RTP/AVP 0 8 97\r\n"
483 "a=rtpmap:0 PCMU/8000\r\n"
484 "a=rtpmap:8 PCMA/8000\r\n"
485 "a=rtpmap:97 iLBC/8000\r\n"
486 "m=video 51372 RTP/AVP 31 32\r\n"
487 "a=rtpmap:31 H261/90000\r\n"
488 "a=rtpmap:32 MPV/90000\r\n",
489 /* Bob's capability: */
490 "v=0\r\n"
491 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
492 "s=-\r\n"
493 "c=IN IP4 host.biloxi.example.com\r\n"
494 "t=0 0\r\n"
495 "m=audio 49174 RTP/AVP 0\r\n"
496 "a=rtpmap:0 PCMU/8000\r\n"
497 "m=video 49170 RTP/AVP 32\r\n"
498 "a=rtpmap:32 MPV/90000\r\n",
499 /* This is how Bob's media should look like now: */
500 "v=0\r\n"
501 "o=bob 2808844564 2808844564 IN IP4 host.biloxi.example.com\r\n"
502 "s=-\r\n"
503 "c=IN IP4 host.biloxi.example.com\r\n"
504 "t=0 0\r\n"
505 "m=audio 49174 RTP/AVP 0\r\n"
506 "a=rtpmap:0 PCMU/8000\r\n"
507 "m=video 49170 RTP/AVP 32\r\n"
508 "a=rtpmap:32 MPV/90000\r\n"
509 }
510 }
511 },
512
513 /* test 6: */
514 {
515 /*********************************************************************
516 * RFC 4317 Sample 2.2: Audio and Video 2 (Alice's view)
517 *
518 * Difference:
519 * - Bob's initial capability version number
520 */
521 "RFC 4317 section 2.2: Audio and Video 2 (Alice's view)",
522 2,
523 {
524 {
525 LOCAL_OFFER,
526 /* Alice sends offer: */
527 "v=0\r\n"
528 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
529 "s=alice\r\n"
530 "c=IN IP4 host.atlanta.example.com\r\n"
531 "t=0 0\r\n"
532 "m=audio 49170 RTP/AVP 0 8 97\r\n"
533 "a=rtpmap:0 PCMU/8000\r\n"
534 "a=rtpmap:8 PCMA/8000\r\n"
535 "a=rtpmap:97 iLBC/8000\r\n"
536 "m=video 51372 RTP/AVP 31 32\r\n"
537 "a=rtpmap:31 H261/90000\r\n"
538 "a=rtpmap:32 MPV/90000\r\n",
539 /* Bob's answer: */
540 "v=0\r\n"
541 "o=bob 2808844564 2808844564 IN IP4 host.biloxi.example.com\r\n"
542 "s=bob\r\n"
543 "c=IN IP4 host.biloxi.example.com\r\n"
544 "t=0 0\r\n"
545 "m=audio 49172 RTP/AVP 0 8\r\n"
546 "a=rtpmap:0 PCMU/8000\r\n"
547 "a=rtpmap:8 PCMA/8000\r\n"
548 "m=video 0 RTP/AVP 31\r\n"
549 "a=rtpmap:31 H261/90000\r\n",
550 /* This is how Alice's media should look like now: */
551 "v=0\r\n"
552 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
553 "s=alice\r\n"
554 "c=IN IP4 host.atlanta.example.com\r\n"
555 "t=0 0\r\n"
556 "m=audio 49170 RTP/AVP 0 8\r\n"
557 "a=rtpmap:0 PCMU/8000\r\n"
558 "a=rtpmap:8 PCMA/8000\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +0000559 // By #1088, the formats won't be negotiated when the media has port 0.
560 //"m=video 0 RTP/AVP 31\r\n"
561 "m=video 0 RTP/AVP 31 32\r\n"
562 //"a=rtpmap:31 H261/90000\r\n" /* <-- this is not necessary (port 0) */
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000563 },
564 {
565 LOCAL_OFFER,
566 /* Alice sends updated offer: */
567 "v=0\r\n"
568 "o=alice 2890844526 2890844527 IN IP4 host.atlanta.example.com\r\n"
569 "s=alice\r\n"
570 "c=IN IP4 host.atlanta.example.com\r\n"
571 "t=0 0\r\n"
572 "m=audio 51372 RTP/AVP 0\r\n"
573 "a=rtpmap:0 PCMU/8000\r\n"
574 "m=video 0 RTP/AVP 31\r\n"
575 "a=rtpmap:31 H261/90000\r\n",
576 /* Bob's answer: */
577 "v=0\r\n"
578 "o=bob 2808844564 2808844565 IN IP4 host.biloxi.example.com\r\n"
579 "s=bob\r\n"
580 "c=IN IP4 host.biloxi.example.com\r\n"
581 "t=0 0\r\n"
582 "m=audio 49172 RTP/AVP 0\r\n"
583 "a=rtpmap:0 PCMU/8000\r\n"
584 "m=video 0 RTP/AVP 31\r\n"
585 "a=rtpmap:31 H261/90000\r\n",
586 /* This is how Alice's SDP should look like: */
587 "v=0\r\n"
588 "o=alice 2890844526 2890844527 IN IP4 host.atlanta.example.com\r\n"
589 "s=alice\r\n"
590 "c=IN IP4 host.atlanta.example.com\r\n"
591 "t=0 0\r\n"
592 "m=audio 51372 RTP/AVP 0\r\n"
593 "a=rtpmap:0 PCMU/8000\r\n"
594 "m=video 0 RTP/AVP 31\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +0000595 //"a=rtpmap:31 H261/90000\r\n" /* <-- this is not necessary (port 0) */
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000596 }
597 }
598 },
599
600 /* test 7: */
601 {
602 /*********************************************************************
603 * RFC 4317 Sample 2.2: Audio and Video 2 (Bob's view)
604 *
605 * Difference:
606 * - Bob's initial capability version number
607 */
608 "RFC 4317 section 2.2: Audio and Video 2 (Bob's view)",
609 2,
610 {
611 {
612 REMOTE_OFFER,
613 /* Received offer from alice: */
614 "v=0\r\n"
615 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
616 "s=alice\r\n"
617 "c=IN IP4 host.atlanta.example.com\r\n"
618 "t=0 0\r\n"
619 "m=audio 49170 RTP/AVP 0 8 97\r\n"
620 "a=rtpmap:0 PCMU/8000\r\n"
621 "a=rtpmap:8 PCMA/8000\r\n"
622 "a=rtpmap:97 iLBC/8000\r\n"
623 "m=video 51372 RTP/AVP 31 32\r\n"
624 "a=rtpmap:31 H261/90000\r\n"
625 "a=rtpmap:32 MPV/90000\r\n",
626 /* Bob's initial capability: */
627 "v=0\r\n"
628 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
629 "s=bob\r\n"
630 "c=IN IP4 host.biloxi.example.com\r\n"
631 "t=0 0\r\n"
632 "m=audio 49172 RTP/AVP 0 8\r\n"
633 "a=rtpmap:0 PCMU/8000\r\n"
634 "a=rtpmap:8 PCMA/8000\r\n"
635 "m=video 0 RTP/AVP 31\r\n"
636 "a=rtpmap:31 H261/90000\r\n",
637 /* This is how Bob's answer should look like now: */
638 "v=0\r\n"
639 "o=bob 2808844564 2808844564 IN IP4 host.biloxi.example.com\r\n"
640 "s=bob\r\n"
641 "c=IN IP4 host.biloxi.example.com\r\n"
642 "t=0 0\r\n"
643 "m=audio 49172 RTP/AVP 0\r\n"
644 "a=rtpmap:0 PCMU/8000\r\n"
645 "m=video 0 RTP/AVP 31\r\n"
646 "a=rtpmap:31 H261/90000\r\n"
647 },
648 {
649 REMOTE_OFFER,
650 /* Received updated offer from Alice: */
651 "v=0\r\n"
652 "o=alice 2890844526 2890844527 IN IP4 host.atlanta.example.com\r\n"
653 "s=alice\r\n"
654 "c=IN IP4 host.atlanta.example.com\r\n"
655 "t=0 0\r\n"
656 "m=audio 51372 RTP/AVP 0\r\n"
657 "a=rtpmap:0 PCMU/8000\r\n"
658 "m=video 0 RTP/AVP 31\r\n"
659 "a=rtpmap:31 H261/90000\r\n",
660 /* Bob's answer: */
661 NULL,
662 /* This is how Bob's answer should look like: */
663 "v=0\r\n"
664 "o=bob 2808844564 2808844565 IN IP4 host.biloxi.example.com\r\n"
665 "s=bob\r\n"
666 "c=IN IP4 host.biloxi.example.com\r\n"
667 "t=0 0\r\n"
668 "m=audio 49172 RTP/AVP 0\r\n"
669 "a=rtpmap:0 PCMU/8000\r\n"
670 "m=video 0 RTP/AVP 31\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +0000671 //"a=rtpmap:31 H261/90000\r\n" /* <-- this is not necessary (port 0) */
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000672 }
673 }
674 },
675
676 /* test 8: */
677 {
678 /*********************************************************************
679 * RFC 4317 Sample 2.4: Audio and Telephone-Events (Alice's view)
680 *
681 */
682
683 "RFC 4317 section 2.4: Audio and Telephone-Events (Alice's view)",
684 1,
685 {
686 {
687 LOCAL_OFFER,
688 /* Alice sends offer: */
689 "v=0\r\n"
690 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
691 "s=alice\r\n"
692 "c=IN IP4 host.atlanta.example.com\r\n"
693 "t=0 0\r\n"
694 "m=audio 49170 RTP/AVP 0 97\r\n"
695 "a=rtpmap:0 PCMU/8000\r\n"
696 "a=rtpmap:97 iLBC/8000\r\n"
697 "m=audio 49172 RTP/AVP 98\r\n"
698 "a=rtpmap:98 telephone-event/8000\r\n"
699 "a=sendonly\r\n",
700 /* Received Bob's answer: */
701 "v=0\r\n"
702 "o=bob 2808844564 2808844564 IN IP4 host.biloxi.example.com\r\n"
703 "s=bob\r\n"
704 "c=IN IP4 host.biloxi.example.com\r\n"
705 "t=0 0\r\n"
706 "m=audio 49172 RTP/AVP 97\r\n"
707 "a=rtpmap:97 iLBC/8000\r\n"
708 "m=audio 49174 RTP/AVP 98\r\n"
709 "a=rtpmap:98 telephone-event/8000\r\n"
710 "a=recvonly\r\n",
711 /* Alice's SDP now: */
712 "v=0\r\n"
713 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
714 "s=alice\r\n"
715 "c=IN IP4 host.atlanta.example.com\r\n"
716 "t=0 0\r\n"
717 "m=audio 49170 RTP/AVP 97\r\n"
718 "a=rtpmap:97 iLBC/8000\r\n"
719 "m=audio 49172 RTP/AVP 98\r\n"
720 "a=rtpmap:98 telephone-event/8000\r\n"
721 "a=sendonly\r\n"
722 }
723 }
724 },
725
726
727 /* test 9: */
728 {
729 /*********************************************************************
730 * RFC 4317 Sample 2.4: Audio and Telephone-Events (Bob's view)
731 *
732 * Difference:
733 * - Bob's initial SDP version number
734 * - Bob's capability are added with more formats, and the
735 * stream order is interchanged to test the negotiator.
736 */
737
738 "RFC 4317 section 2.4: Audio and Telephone-Events (Bob's view)",
739 1,
740 {
741 {
742 REMOTE_OFFER,
743 /* Received Alice's offer: */
744 "v=0\r\n"
745 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
746 "s=alice\r\n"
747 "c=IN IP4 host.atlanta.example.com\r\n"
748 "t=0 0\r\n"
749 "m=audio 49170 RTP/AVP 0 97\r\n"
750 "a=rtpmap:0 PCMU/8000\r\n"
751 "a=rtpmap:97 iLBC/8000\r\n"
752 "m=audio 49172 RTP/AVP 98\r\n"
753 "a=rtpmap:98 telephone-event/8000\r\n"
754 "a=sendonly\r\n",
755 /* Bob's initial capability: */
756 "v=0\r\n"
757 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
758 "s=bob\r\n"
759 "c=IN IP4 host.biloxi.example.com\r\n"
760 "t=0 0\r\n"
761 "m=audio 49174 RTP/AVP 4 98\r\n"
762 "a=rtpmap:98 telephone-event/8000\r\n"
763 "m=audio 49172 RTP/AVP 97 8 99\r\n"
764 "a=rtpmap:97 iLBC/8000\r\n"
Nanang Izzuddina5538ab2008-05-07 15:30:34 +0000765 "a=rtpmap:99 telephone-event/8000\r\n",
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000766 /* Bob's answer should be: */
767 "v=0\r\n"
768 "o=bob 2808844564 2808844564 IN IP4 host.biloxi.example.com\r\n"
769 "s=bob\r\n"
770 "c=IN IP4 host.biloxi.example.com\r\n"
771 "t=0 0\r\n"
772 "m=audio 49172 RTP/AVP 97\r\n"
773 "a=rtpmap:97 iLBC/8000\r\n"
774 "m=audio 49174 RTP/AVP 98\r\n"
775 "a=rtpmap:98 telephone-event/8000\r\n"
776 "a=recvonly\r\n"
777 }
778 }
779 },
780
781 /* test 10: */
782 {
783 /*********************************************************************
784 * RFC 4317 Sample 2.6: Audio with Telephone-Events (Alice's view)
785 *
786 */
787
788 "RFC 4317 section 2.6: Audio with Telephone-Events (Alice's view)",
789 1,
790 {
791 {
792 LOCAL_OFFER,
793 /* Alice sends offer: */
794 "v=0\r\n"
795 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
796 "s=alice\r\n"
797 "c=IN IP4 host.atlanta.example.com\r\n"
798 "t=0 0\r\n"
799 "m=audio 49170 RTP/AVP 0\r\n"
800 "a=rtpmap:0 PCMU/8000\r\n"
801 "m=audio 51372 RTP/AVP 97 101\r\n"
802 "a=rtpmap:97 iLBC/8000\r\n"
803 "a=rtpmap:101 telephone-event/8000\r\n",
804 /* Received bob's answer: */
805 "v=0\r\n"
806 "o=bob 2808844564 2808844564 IN IP4 host.biloxi.example.com\r\n"
807 "s=bob\r\n"
808 "c=IN IP4 host.biloxi.example.com\r\n"
809 "t=0 0\r\n"
810 "m=audio 0 RTP/AVP 0\r\n"
811 "a=rtpmap:0 PCMU/8000\r\n"
812 "m=audio 49170 RTP/AVP 97 101\r\n"
813 "a=rtpmap:97 iLBC/8000\r\n"
814 "a=rtpmap:101 telephone-event/8000\r\n",
815 /* Alice's local SDP should be: */
816 "v=0\r\n"
817 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
818 "s=alice\r\n"
819 "c=IN IP4 host.atlanta.example.com\r\n"
820 "t=0 0\r\n"
821 "m=audio 0 RTP/AVP 0\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +0000822 //"a=rtpmap:0 PCMU/8000\r\n" /* <-- this is not necessary (port 0) */
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000823 "m=audio 51372 RTP/AVP 97 101\r\n"
824 "a=rtpmap:97 iLBC/8000\r\n"
825 "a=rtpmap:101 telephone-event/8000\r\n"
826 }
827 }
828 },
829
830 /* test 11: */
831 {
832 /*********************************************************************
833 * RFC 4317 Sample 2.6: Audio with Telephone-Events (Bob's view)
834 *
835 * Difference:
836 * - Bob's SDP version number
837 * - Bob's initial capability are expanded with multiple m lines
838 * and more formats
839 */
840
841 "RFC 4317 section 2.6: Audio with Telephone-Events (Bob's view)",
842 1,
843 {
844 {
845 REMOTE_OFFER,
846 /* Received Alice's offer: */
847 "v=0\r\n"
848 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
849 "s=alice\r\n"
850 "c=IN IP4 host.atlanta.example.com\r\n"
851 "t=0 0\r\n"
852 "m=audio 49170 RTP/AVP 0\r\n"
853 "a=rtpmap:0 PCMU/8000\r\n"
854 "m=audio 51372 RTP/AVP 97 101\r\n"
855 "a=rtpmap:97 iLBC/8000\r\n"
856 "a=rtpmap:101 telephone-event/8000\r\n",
857 /* Bob's initial capability also has video: */
858 "v=0\r\n"
859 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
860 "s=bob\r\n"
861 "c=IN IP4 host.biloxi.example.com\r\n"
862 "t=0 0\r\n"
863 "m=audio 49170 RTP/AVP 4 97 101\r\n"
864 "a=rtpmap:4 G723/8000\r\n"
865 "a=rtpmap:97 iLBC/8000\r\n"
866 "a=rtpmap:101 telephone-event/8000\r\n"
867 "m=video 1000 RTP/AVP 31\r\n"
868 "a=rtpmap:31 H261/90000\r\n",
869 /* Bob's answer should be: */
870 "v=0\r\n"
871 "o=bob 2808844564 2808844564 IN IP4 host.biloxi.example.com\r\n"
872 "s=bob\r\n"
873 "c=IN IP4 host.biloxi.example.com\r\n"
874 "t=0 0\r\n"
875 "m=audio 0 RTP/AVP 0\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +0000876 //"a=rtpmap:0 PCMU/8000\r\n" /* <-- this is not necessary (port 0) */
Benny Prijono4ea0bf12006-02-02 19:16:07 +0000877 "m=audio 49170 RTP/AVP 97 101\r\n"
878 "a=rtpmap:97 iLBC/8000\r\n"
879 "a=rtpmap:101 telephone-event/8000\r\n",
880 }
881 }
882 },
883
Nanang Izzuddina5538ab2008-05-07 15:30:34 +0000884 /* test 12: */
885 {
886 /*********************************************************************
887 * Ticket #527: More lenient SDP negotiator.
888 */
889
890 "Ticket #527 scenario #1: Partial answer",
891 1,
892 {
893 {
894 LOCAL_OFFER,
895 /* Alice sends offer audio and video: */
896 "v=0\r\n"
897 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
898 "s=alice\r\n"
899 "c=IN IP4 host.atlanta.example.com\r\n"
900 "t=0 0\r\n"
901 "m=audio 49170 RTP/AVP 0\r\n"
902 "a=rtpmap:0 PCMU/8000\r\n"
903 "m=video 4000 RTP/AVP 31\r\n"
904 "a=rtpmap:31 H261/90000\r\n",
905 /* Receive Bob's answer only audio: */
906 "v=0\r\n"
907 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
908 "s=bob\r\n"
909 "c=IN IP4 host.biloxi.example.com\r\n"
910 "t=0 0\r\n"
911 "m=audio 49170 RTP/AVP 0\r\n"
912 "a=rtpmap:0 PCMU/8000\r\n",
913 /* Alice's local SDP should be: */
914 "v=0\r\n"
915 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
916 "s=alice\r\n"
917 "c=IN IP4 host.atlanta.example.com\r\n"
918 "t=0 0\r\n"
919 "m=audio 49170 RTP/AVP 0\r\n"
920 "a=rtpmap:0 PCMU/8000\r\n"
921 "m=video 0 RTP/AVP 31\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +0000922 //"a=rtpmap:31 H261/90000\r\n" /* <-- this is not necessary (port 0) */
Nanang Izzuddina5538ab2008-05-07 15:30:34 +0000923 "",
924 }
925 }
926 },
927
928 /* test 13: */
929 {
930 /*********************************************************************
931 * Ticket #527: More lenient SDP negotiator.
932 */
933
934 "Ticket #527 scenario #1: Media mismatch in answer",
935 1,
936 {
937 {
938 LOCAL_OFFER,
939 /* Alice sends offer audio and video: */
940 "v=0\r\n"
941 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
942 "s=alice\r\n"
943 "c=IN IP4 host.atlanta.example.com\r\n"
944 "t=0 0\r\n"
945 "m=audio 3000 RTP/AVP 0\r\n"
946 "a=rtpmap:0 PCMU/8000\r\n"
947 "m=video 4000 RTP/AVP 31\r\n"
948 "a=rtpmap:31 H261/90000\r\n",
949 /* Receive Bob's answer two audio: */
950 "v=0\r\n"
951 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
952 "s=bob\r\n"
953 "c=IN IP4 host.biloxi.example.com\r\n"
954 "t=0 0\r\n"
955 "m=audio 49170 RTP/AVP 0\r\n"
956 "a=rtpmap:0 PCMU/8000\r\n"
957 "m=audio 49172 RTP/AVP 0\r\n"
958 "a=rtpmap:0 PCMU/8000\r\n",
959 /* Alice's local SDP should be: */
960 "v=0\r\n"
961 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
962 "s=alice\r\n"
963 "c=IN IP4 host.atlanta.example.com\r\n"
964 "t=0 0\r\n"
965 "m=audio 3000 RTP/AVP 0\r\n"
966 "a=rtpmap:0 PCMU/8000\r\n"
967 "m=video 0 RTP/AVP 31\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +0000968 //"a=rtpmap:31 H261/90000\r\n" /* <-- this is not necessary (port 0) */
Nanang Izzuddina5538ab2008-05-07 15:30:34 +0000969 "",
970 }
971 }
972 },
973
974 /* test 14: */
975 {
976 /*********************************************************************
977 * Ticket #527: More lenient SDP negotiator.
978 */
979
980 "Ticket #527 scenario #2: Modify offer - partial streams",
981 2,
982 {
983 {
984 LOCAL_OFFER,
985 /* Alice sends offer: */
986 "v=0\r\n"
987 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
988 "s=alice\r\n"
989 "c=IN IP4 host.atlanta.example.com\r\n"
990 "t=0 0\r\n"
991 "m=audio 3000 RTP/AVP 0\r\n"
992 "a=rtpmap:0 PCMU/8000\r\n"
993 "m=audio 3100 RTP/AVP 0\r\n"
994 "a=rtpmap:0 PCMU/8000\r\n"
995 "m=video 3200 RTP/AVP 31\r\n"
996 "a=rtpmap:31 H261/90000\r\n"
997 "",
998 /* Receive Bob's answer: */
999 "v=0\r\n"
1000 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
1001 "s=bob\r\n"
1002 "c=IN IP4 host.biloxi.example.com\r\n"
1003 "t=0 0\r\n"
1004 "m=audio 4000 RTP/AVP 0\r\n"
1005 "a=rtpmap:0 PCMU/8000\r\n"
1006 "m=audio 4100 RTP/AVP 0\r\n"
1007 "a=rtpmap:0 PCMU/8000\r\n"
1008 "m=video 4200 RTP/AVP 31\r\n"
1009 "a=rtpmap:31 H261/90000\r\n"
1010 "",
1011 /* Alice's local SDP should be: */
1012 "v=0\r\n"
1013 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
1014 "s=alice\r\n"
1015 "c=IN IP4 host.atlanta.example.com\r\n"
1016 "t=0 0\r\n"
1017 "m=audio 3000 RTP/AVP 0\r\n"
1018 "a=rtpmap:0 PCMU/8000\r\n"
1019 "m=audio 3100 RTP/AVP 0\r\n"
1020 "a=rtpmap:0 PCMU/8000\r\n"
1021 "m=video 3200 RTP/AVP 31\r\n"
1022 "a=rtpmap:31 H261/90000\r\n"
1023 "",
1024 },
1025 {
1026 LOCAL_OFFER,
1027 /* Alice modifies offer with only specify one audio: */
1028 "v=0\r\n"
1029 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
1030 "s=alice\r\n"
1031 "c=IN IP4 host.atlanta.example.com\r\n"
1032 "t=0 0\r\n"
1033 "m=audio 5200 RTP/AVP 0\r\n"
1034 "a=rtpmap:0 PCMU/8000\r\n"
1035 "",
1036 /* Receive Bob's answer: */
1037 "v=0\r\n"
1038 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
1039 "s=bob\r\n"
1040 "c=IN IP4 host.biloxi.example.com\r\n"
1041 "t=0 0\r\n"
1042 "m=audio 7000 RTP/AVP 0\r\n"
1043 "a=rtpmap:0 PCMU/8000\r\n"
1044 "m=audio 0 RTP/AVP 0\r\n"
1045 "a=rtpmap:0 PCMU/8000\r\n"
1046 "m=video 0 RTP/AVP 31\r\n"
1047 "a=rtpmap:31 H261/90000\r\n"
1048 "",
1049 /* Alice's local SDP should be: */
1050 "v=0\r\n"
1051 "o=alice 2890844526 2890844527 IN IP4 host.atlanta.example.com\r\n"
1052 "s=alice\r\n"
1053 "c=IN IP4 host.atlanta.example.com\r\n"
1054 "t=0 0\r\n"
1055 "m=audio 5200 RTP/AVP 0\r\n"
1056 "a=rtpmap:0 PCMU/8000\r\n"
1057 "m=audio 0 RTP/AVP 0\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +00001058 //"a=rtpmap:0 PCMU/8000\r\n" /* <-- this is not necessary (port 0) */
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001059 "m=video 0 RTP/AVP 31\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +00001060 //"a=rtpmap:31 H261/90000\r\n" /* <-- this is not necessary (port 0) */
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001061 "",
1062 }
1063 }
1064 },
1065
1066 /* test 15: */
1067 {
1068 /*********************************************************************
1069 * Ticket #527: More lenient SDP negotiator.
1070 */
1071
1072 "Ticket #527 scenario #2: Modify offer - unordered m= lines",
1073 2,
1074 {
1075 {
1076 LOCAL_OFFER,
1077 /* Alice sends offer: */
1078 "v=0\r\n"
1079 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
1080 "s=alice\r\n"
1081 "c=IN IP4 host.atlanta.example.com\r\n"
1082 "t=0 0\r\n"
1083 "m=audio 3000 RTP/AVP 0\r\n"
1084 "a=rtpmap:0 PCMU/8000\r\n"
1085 "m=video 3200 RTP/AVP 31\r\n"
1086 "a=rtpmap:31 H261/90000\r\n"
1087 "",
1088 /* Receive Bob's answer: */
1089 "v=0\r\n"
1090 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
1091 "s=bob\r\n"
1092 "c=IN IP4 host.biloxi.example.com\r\n"
1093 "t=0 0\r\n"
1094 "m=audio 4000 RTP/AVP 0\r\n"
1095 "a=rtpmap:0 PCMU/8000\r\n"
1096 "m=video 4200 RTP/AVP 31\r\n"
1097 "a=rtpmap:31 H261/90000\r\n"
1098 "",
1099 /* Alice's local SDP should be: */
1100 "v=0\r\n"
1101 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
1102 "s=alice\r\n"
1103 "c=IN IP4 host.atlanta.example.com\r\n"
1104 "t=0 0\r\n"
1105 "m=audio 3000 RTP/AVP 0\r\n"
1106 "a=rtpmap:0 PCMU/8000\r\n"
1107 "m=video 3200 RTP/AVP 31\r\n"
1108 "a=rtpmap:31 H261/90000\r\n"
1109 "",
1110 },
1111 {
1112 LOCAL_OFFER,
1113 /* Alice modifies offer with unordered m= lines: */
1114 "v=0\r\n"
1115 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
1116 "s=alice\r\n"
1117 "c=IN IP4 host.atlanta.example.com\r\n"
1118 "t=0 0\r\n"
1119 "m=video 5000 RTP/AVP 31\r\n"
1120 "a=rtpmap:31 H261/90000\r\n"
1121 "m=audio 5200 RTP/AVP 0\r\n"
1122 "a=rtpmap:0 PCMU/8000\r\n"
1123 "",
1124 /* Receive Bob's answer: */
1125 "v=0\r\n"
1126 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
1127 "s=bob\r\n"
1128 "c=IN IP4 host.biloxi.example.com\r\n"
1129 "t=0 0\r\n"
1130 "m=audio 7000 RTP/AVP 0\r\n"
1131 "a=rtpmap:0 PCMU/8000\r\n"
1132 "m=video 2000 RTP/AVP 31\r\n"
1133 "a=rtpmap:31 H261/90000\r\n"
1134 "",
1135 /* Alice's local SDP should be: */
1136 "v=0\r\n"
1137 "o=alice 2890844526 2890844527 IN IP4 host.atlanta.example.com\r\n"
1138 "s=alice\r\n"
1139 "c=IN IP4 host.atlanta.example.com\r\n"
1140 "t=0 0\r\n"
1141 "m=audio 5200 RTP/AVP 0\r\n"
1142 "a=rtpmap:0 PCMU/8000\r\n"
1143 "m=video 5000 RTP/AVP 31\r\n"
1144 "a=rtpmap:31 H261/90000\r\n"
1145 "",
1146 }
1147 }
1148 },
1149
1150 /* test 16: */
1151 {
1152 /*********************************************************************
1153 * Ticket #527: More lenient SDP negotiator.
1154 */
1155
1156 "Ticket #527 scenario #2: Modify offer - partial & unordered streams",
1157 2,
1158 {
1159 {
1160 LOCAL_OFFER,
1161 /* Alice sends offer: */
1162 "v=0\r\n"
1163 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
1164 "s=alice\r\n"
1165 "c=IN IP4 host.atlanta.example.com\r\n"
1166 "t=0 0\r\n"
1167 "m=audio 3000 RTP/AVP 0\r\n"
1168 "a=rtpmap:0 PCMU/8000\r\n"
1169 "m=audio 3200 RTP/AVP 0\r\n"
1170 "a=rtpmap:0 PCMU/8000\r\n"
1171 "m=video 3400 RTP/AVP 31\r\n"
1172 "a=rtpmap:31 H261/90000\r\n"
1173 "",
1174 /* Receive Bob's answer: */
1175 "v=0\r\n"
1176 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
1177 "s=bob\r\n"
1178 "c=IN IP4 host.biloxi.example.com\r\n"
1179 "t=0 0\r\n"
1180 "m=audio 4000 RTP/AVP 0\r\n"
1181 "a=rtpmap:0 PCMU/8000\r\n"
1182 "m=audio 4200 RTP/AVP 0\r\n"
1183 "a=rtpmap:0 PCMU/8000\r\n"
1184 "m=video 4400 RTP/AVP 31\r\n"
1185 "a=rtpmap:31 H261/90000\r\n"
1186 "",
1187 /* Alice's local SDP should be: */
1188 "v=0\r\n"
1189 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
1190 "s=alice\r\n"
1191 "c=IN IP4 host.atlanta.example.com\r\n"
1192 "t=0 0\r\n"
1193 "m=audio 3000 RTP/AVP 0\r\n"
1194 "a=rtpmap:0 PCMU/8000\r\n"
1195 "m=audio 3200 RTP/AVP 0\r\n"
1196 "a=rtpmap:0 PCMU/8000\r\n"
1197 "m=video 3400 RTP/AVP 31\r\n"
1198 "a=rtpmap:31 H261/90000\r\n"
1199 "",
1200 },
1201 {
1202 LOCAL_OFFER,
1203 /* Alice modifies offer by specifying partial and unordered media: */
1204 "v=0\r\n"
1205 "o=alice 2890844526 2890844526 IN IP4 host.atlanta.example.com\r\n"
1206 "s=alice\r\n"
1207 "c=IN IP4 host.atlanta.example.com\r\n"
1208 "t=0 0\r\n"
1209 "m=video 5000 RTP/AVP 31\r\n"
1210 "a=rtpmap:31 H261/90000\r\n"
1211 "m=audio 7000 RTP/AVP 0\r\n"
1212 "a=rtpmap:0 PCMU/8000\r\n"
1213 "",
1214 /* Receive Bob's answer: */
1215 "v=0\r\n"
1216 "o=bob 2808844564 2808844563 IN IP4 host.biloxi.example.com\r\n"
1217 "s=bob\r\n"
1218 "c=IN IP4 host.biloxi.example.com\r\n"
1219 "t=0 0\r\n"
1220 "m=audio 4000 RTP/AVP 0\r\n"
1221 "a=rtpmap:0 PCMU/8000\r\n"
1222 "m=audio 0 RTP/AVP 0\r\n"
1223 "a=rtpmap:0 PCMU/8000\r\n"
1224 "m=video 4400 RTP/AVP 31\r\n"
1225 "a=rtpmap:31 H261/90000\r\n"
1226 "",
1227 /* Alice's local SDP should be: */
1228 "v=0\r\n"
1229 "o=alice 2890844526 2890844527 IN IP4 host.atlanta.example.com\r\n"
1230 "s=alice\r\n"
1231 "c=IN IP4 host.atlanta.example.com\r\n"
1232 "t=0 0\r\n"
1233 "m=audio 7000 RTP/AVP 0\r\n"
1234 "a=rtpmap:0 PCMU/8000\r\n"
1235 "m=audio 0 RTP/AVP 0\r\n"
Nanang Izzuddin16852b32010-06-04 13:41:34 +00001236 //"a=rtpmap:0 PCMU/8000\r\n" /* <-- this is not necessary (port 0) */
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001237 "m=video 5000 RTP/AVP 31\r\n"
1238 "a=rtpmap:31 H261/90000\r\n"
1239 "",
1240 }
1241 }
1242 },
1243
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001244};
1245
1246static const char *find_diff(const char *s1, const char *s2,
1247 int *line)
1248{
1249 *line = 1;
1250 while (*s2 && *s1) {
1251 if (*s2 != *s1)
1252 return s2;
1253 if (*s2 == '\n')
1254 ++*line;
1255 ++s2, ++s1;
1256 }
1257
1258 return s2;
1259}
1260
1261static int compare_sdp_string(const char *cmp_title,
1262 const char *title1,
1263 const pjmedia_sdp_session *sdp1,
1264 const char *title2,
1265 const pjmedia_sdp_session *sdp2,
1266 pj_status_t logical_cmp)
1267{
1268 char sdpbuf1[1024], sdpbuf2[1024];
1269 pj_ssize_t len1, len2;
1270
1271 len1 = pjmedia_sdp_print(sdp1, sdpbuf1, sizeof(sdpbuf1));
1272 if (len1 < 1) {
1273 PJ_LOG(3,(THIS_FILE," error: printing sdp1"));
1274 return -1;
1275 }
1276 sdpbuf1[len1] = '\0';
1277
1278 len2 = pjmedia_sdp_print(sdp2, sdpbuf2, sizeof(sdpbuf2));
1279 if (len2 < 1) {
1280 PJ_LOG(3,(THIS_FILE," error: printing sdp2"));
1281 return -1;
1282 }
1283 sdpbuf2[len2] = '\0';
1284
1285 if (logical_cmp != PJ_SUCCESS) {
1286 char errbuf[80];
1287
1288 pjmedia_strerror(logical_cmp, errbuf, sizeof(errbuf));
1289
1290 PJ_LOG(3,(THIS_FILE,"%s mismatch: %s\n"
1291 "%s:\n"
1292 "%s\n"
1293 "%s:\n"
1294 "%s\n",
1295 cmp_title,
1296 errbuf,
1297 title1, sdpbuf1,
1298 title2, sdpbuf2));
1299
1300 return -1;
1301
1302 } else if (strcmp(sdpbuf1, sdpbuf2) != 0) {
1303 int line;
1304 const char *diff;
1305
1306 PJ_LOG(3,(THIS_FILE,"%s mismatch:\n"
1307 "%s:\n"
1308 "%s\n"
1309 "%s:\n"
1310 "%s\n",
1311 cmp_title,
1312 title1, sdpbuf1,
1313 title2, sdpbuf2));
1314
1315 diff = find_diff(sdpbuf1, sdpbuf2, &line);
1316 PJ_LOG(3,(THIS_FILE,"Difference: line %d:\n"
1317 "%s",
1318 line, diff));
1319 return -1;
1320
1321 } else {
1322 return 0;
1323 }
1324
1325}
1326
1327static int offer_answer_test(pj_pool_t *pool, pjmedia_sdp_neg **p_neg,
1328 struct offer_answer *oa)
1329{
1330 pjmedia_sdp_session *sdp1;
1331 pjmedia_sdp_neg *neg;
1332 pj_status_t status;
1333
Benny Prijono06973132009-01-27 10:05:48 +00001334 status = pjmedia_sdp_parse(pool, oa->sdp1, pj_ansi_strlen(oa->sdp1),
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001335 &sdp1);
1336 if (status != PJ_SUCCESS) {
1337 app_perror(status, " error: unexpected parse status for sdp1");
1338 return -10;
1339 }
1340
1341 status = pjmedia_sdp_validate(sdp1);
1342 if (status != PJ_SUCCESS) {
1343 app_perror(status, " error: sdp1 validation failed");
1344 return -15;
1345 }
1346
1347 neg = *p_neg;
1348
1349 if (oa->type == LOCAL_OFFER) {
1350
1351 /*
1352 * Local creates offer first.
1353 */
1354 pjmedia_sdp_session *sdp2, *sdp3;
1355 const pjmedia_sdp_session *active;
1356
1357 if (neg == NULL) {
1358 /* Create negotiator with local offer. */
1359 status = pjmedia_sdp_neg_create_w_local_offer(pool, sdp1, &neg);
1360 if (status != PJ_SUCCESS) {
1361 app_perror(status, " error: pjmedia_sdp_neg_create_w_local_offer");
1362 return -20;
1363 }
1364 *p_neg = neg;
1365
1366 } else {
1367 /* Modify local offer */
1368 status = pjmedia_sdp_neg_modify_local_offer(pool, neg, sdp1);
1369 if (status != PJ_SUCCESS) {
1370 app_perror(status, " error: pjmedia_sdp_neg_modify_local_offer");
1371 return -30;
1372 }
1373 }
1374
1375 /* Parse and validate remote answer */
Benny Prijono06973132009-01-27 10:05:48 +00001376 status = pjmedia_sdp_parse(pool, oa->sdp2, pj_ansi_strlen(oa->sdp2),
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001377 &sdp2);
1378 if (status != PJ_SUCCESS) {
1379 app_perror(status, " error: parsing sdp2");
1380 return -40;
1381 }
1382
1383 status = pjmedia_sdp_validate(sdp2);
1384 if (status != PJ_SUCCESS) {
1385 app_perror(status, " error: sdp2 validation failed");
1386 return -50;
1387 }
1388
1389 /* Give the answer to negotiator. */
Benny Prijonob8528f42006-02-07 19:31:53 +00001390 status = pjmedia_sdp_neg_set_remote_answer(pool, neg, sdp2);
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001391 if (status != PJ_SUCCESS) {
1392 app_perror(status, " error: pjmedia_sdp_neg_rx_remote_answer");
1393 return -60;
1394 }
1395
1396 /* Negotiate remote answer with local answer */
1397 status = pjmedia_sdp_neg_negotiate(pool, neg, 0);
1398 if (status != PJ_SUCCESS) {
1399 app_perror(status, " error: pjmedia_sdp_neg_negotiate");
1400 return -70;
1401 }
1402
1403 /* Get the local active media. */
Benny Prijonob8528f42006-02-07 19:31:53 +00001404 status = pjmedia_sdp_neg_get_active_local(neg, &active);
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001405 if (status != PJ_SUCCESS) {
1406 app_perror(status, " error: pjmedia_sdp_neg_get_local");
1407 return -80;
1408 }
1409
1410 /* Parse and validate the correct active media. */
Benny Prijono06973132009-01-27 10:05:48 +00001411 status = pjmedia_sdp_parse(pool, oa->sdp3, pj_ansi_strlen(oa->sdp3),
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001412 &sdp3);
1413 if (status != PJ_SUCCESS) {
1414 app_perror(status, " error: parsing sdp3");
1415 return -90;
1416 }
1417
1418 status = pjmedia_sdp_validate(sdp3);
1419 if (status != PJ_SUCCESS) {
1420 app_perror(status, " error: sdp3 validation failed");
1421 return -100;
1422 }
1423
1424 /* Compare active with sdp3 */
1425 status = pjmedia_sdp_session_cmp(active, sdp3, 0);
1426 if (status != PJ_SUCCESS) {
1427 app_perror(status, " error: active local comparison mismatch");
1428 compare_sdp_string("Logical cmp after negotiatin remote answer",
1429 "Active local sdp from negotiator", active,
1430 "The correct active local sdp", sdp3,
1431 status);
1432 return -110;
1433 }
1434
1435 /* Compare the string representation oa both sdps */
1436 status = compare_sdp_string("String cmp after negotiatin remote answer",
1437 "Active local sdp from negotiator", active,
1438 "The correct active local sdp", sdp3,
1439 PJ_SUCCESS);
1440 if (status != 0)
1441 return -120;
1442
1443 } else {
1444 /*
1445 * Remote creates offer first.
1446 */
1447
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001448 pjmedia_sdp_session *sdp2 = NULL, *sdp3;
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001449 const pjmedia_sdp_session *answer;
1450
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001451 if (oa->sdp2) {
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001452 /* Parse and validate initial local capability */
Benny Prijono06973132009-01-27 10:05:48 +00001453 status = pjmedia_sdp_parse(pool, oa->sdp2, pj_ansi_strlen(oa->sdp2),
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001454 &sdp2);
1455 if (status != PJ_SUCCESS) {
1456 app_perror(status, " error: parsing sdp2");
1457 return -200;
1458 }
1459
1460 status = pjmedia_sdp_validate(sdp2);
1461 if (status != PJ_SUCCESS) {
1462 app_perror(status, " error: sdp2 validation failed");
1463 return -210;
1464 }
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001465 } else if (neg) {
Benny Prijono2eabad92009-05-06 14:34:13 +00001466 const pjmedia_sdp_session *lsdp;
1467 status = pjmedia_sdp_neg_get_active_local(neg, &lsdp);
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001468 if (status != PJ_SUCCESS) {
1469 app_perror(status,
1470 " error: pjmedia_sdp_neg_get_active_local");
1471 return -215;
1472 }
Benny Prijono2eabad92009-05-06 14:34:13 +00001473 sdp2 = (pjmedia_sdp_session*)lsdp;
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001474 }
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001475
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001476 if (neg == NULL) {
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001477 /* Create negotiator with remote offer. */
1478 status = pjmedia_sdp_neg_create_w_remote_offer(pool, sdp2, sdp1, &neg);
1479 if (status != PJ_SUCCESS) {
1480 app_perror(status, " error: pjmedia_sdp_neg_create_w_remote_offer");
1481 return -220;
1482 }
1483 *p_neg = neg;
1484
1485 } else {
1486 /* Received subsequent offer from remote. */
Benny Prijonob8528f42006-02-07 19:31:53 +00001487 status = pjmedia_sdp_neg_set_remote_offer(pool, neg, sdp1);
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001488 if (status != PJ_SUCCESS) {
1489 app_perror(status, " error: pjmedia_sdp_neg_rx_remote_offer");
1490 return -230;
1491 }
Nanang Izzuddina5538ab2008-05-07 15:30:34 +00001492
1493 status = pjmedia_sdp_neg_set_local_answer(pool, neg, sdp2);
1494 if (status != PJ_SUCCESS) {
1495 app_perror(status, " error: pjmedia_sdp_neg_set_local_answer");
1496 return -235;
1497 }
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001498 }
1499
1500 /* Negotiate. */
1501 status = pjmedia_sdp_neg_negotiate(pool, neg, 0);
1502 if (status != PJ_SUCCESS) {
1503 app_perror(status, " error: pjmedia_sdp_neg_negotiate");
1504 return -240;
1505 }
1506
1507 /* Get our answer. */
Benny Prijonob8528f42006-02-07 19:31:53 +00001508 status = pjmedia_sdp_neg_get_active_local(neg, &answer);
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001509 if (status != PJ_SUCCESS) {
1510 app_perror(status, " error: pjmedia_sdp_neg_get_local");
1511 return -250;
1512 }
1513
1514 /* Parse the correct answer. */
Benny Prijono06973132009-01-27 10:05:48 +00001515 status = pjmedia_sdp_parse(pool, oa->sdp3, pj_ansi_strlen(oa->sdp3),
Benny Prijono4ea0bf12006-02-02 19:16:07 +00001516 &sdp3);
1517 if (status != PJ_SUCCESS) {
1518 app_perror(status, " error: parsing sdp3");
1519 return -260;
1520 }
1521
1522 /* Validate the correct answer. */
1523 status = pjmedia_sdp_validate(sdp3);
1524 if (status != PJ_SUCCESS) {
1525 app_perror(status, " error: sdp3 validation failed");
1526 return -270;
1527 }
1528
1529 /* Compare answer from negotiator and the correct answer */
1530 status = pjmedia_sdp_session_cmp(sdp3, answer, 0);
1531 if (status != PJ_SUCCESS) {
1532 compare_sdp_string("Logical cmp after negotiating remote offer",
1533 "Local answer from negotiator", answer,
1534 "The correct local answer", sdp3,
1535 status);
1536
1537 return -280;
1538 }
1539
1540 /* Compare the string representation oa both answers */
1541 status = compare_sdp_string("String cmp after negotiating remote offer",
1542 "Local answer from negotiator", answer,
1543 "The correct local answer", sdp3,
1544 PJ_SUCCESS);
1545 if (status != 0)
1546 return -290;
1547
1548 }
1549
1550 return 0;
1551}
1552
1553static int perform_test(pj_pool_t *pool, int test_index)
1554{
1555 pjmedia_sdp_neg *neg = NULL;
1556 unsigned i;
1557 int rc;
1558
1559 for (i=0; i<test[test_index].offer_answer_count; ++i) {
1560
1561 rc = offer_answer_test(pool, &neg, &test[test_index].offer_answer[i]);
1562 if (rc != 0) {
1563 PJ_LOG(3,(THIS_FILE, " test %d offer answer %d failed with status %d",
1564 test_index, i, rc));
1565 return rc;
1566 }
1567 }
1568
1569 return 0;
1570}
1571
1572int sdp_neg_test()
1573{
1574 unsigned i;
1575 int status;
1576
1577 for (i=START_TEST; i<PJ_ARRAY_SIZE(test); ++i) {
1578 pj_pool_t *pool;
1579
1580 pool = pj_pool_create(mem, "sdp_neg_test", 4000, 4000, NULL);
1581 if (!pool)
1582 return PJ_ENOMEM;
1583
1584 PJ_LOG(3,(THIS_FILE," test %d: %s", i, test[i].title));
1585 status = perform_test(pool, i);
1586
1587 pj_pool_release(pool);
1588
1589 if (status != 0) {
1590 return status;
1591 }
1592 }
1593
1594 return 0;
1595}
1596