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