1 /*
2 * This file is part of the Sofia-SIP package
3 *
4 * Copyright (C) 2005 Nokia Corporation.
5 *
6 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21 * 02110-1301 USA
22 *
23 */
24
25 /**@CFILE test_cancel_bye.c
26 * @brief Test CANCEL, weird BYE and handle destroy
27 *
28 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
29 * @author Martti Mela <Martti Mela@nokia.com>
30 *
31 * @date Created: Wed Aug 17 12:12:12 EEST 2005 ppessi
32 */
33
34 #include "config.h"
35
36 #include "test_nua.h"
37 #include <sofia-sip/su_tag_class.h>
38
39 #if HAVE_FUNC
40 #elif HAVE_FUNCTION
41 #define __func__ __FUNCTION__
42 #else
43 #define __func__ "test_cancel_bye"
44 #endif
45
46 /* ======================================================================== */
47
48 /* Cancel cases:
49
50
51 A B
52 |-------INVITE------>|
53 |<----100 Trying-----|
54 | |
55 |------CANCEL------->|
56 |<------200 OK-------|
57 | |
58 |<-------487---------|
59 |--------ACK-------->|
60 | |
61 | |
62
63 Client transitions:
64 INIT -(C1)-> CALLING -(C6a)-> TERMINATED
65
66 Server transitions:
67 INIT -(S1)-> RECEIVED -(S6a)-> TERMINATED
68
69 A B
70 |-------INVITE------>|
71 |<----100 Trying-----|
72 | |
73 |<----180 Ringing----|
74 | |
75 |------CANCEL------->|
76 |<------200 OK-------|
77 | |
78 |<-------487---------|
79 |--------ACK-------->|
80 | |
81 | |
82
83 Client transitions:
84 INIT -(C1)-> CALLING -(C2)-> PROCEEDING -(C6b)-> TERMINATED
85
86 Server transitions:
87 INIT -(S1)-> RECEIVED -(S2a)-> EARLY -(S6b)-> TERMINATED
88
89 */
90
cancel_when_calling(CONDITION_PARAMS)91 int cancel_when_calling(CONDITION_PARAMS)
92 {
93 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
94 return 0;
95
96 save_event_in_list(ctx, event, ep, call);
97
98 switch (callstate(tags)) {
99 case nua_callstate_calling:
100 CANCEL(ep, call, nh,
101 /* sf.net bug #173323 */
102 SIPTAG_CALL_ID_STR("non-existing-call-id"),
103 TAG_END());
104 return 0;
105 case nua_callstate_terminated:
106 return 1;
107 default:
108 return 0;
109 }
110 }
111
bye_when_calling(CONDITION_PARAMS)112 int bye_when_calling(CONDITION_PARAMS)
113 {
114 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
115 return 0;
116
117 save_event_in_list(ctx, event, ep, call);
118
119 switch (callstate(tags)) {
120 case nua_callstate_calling:
121 BYE(ep, call, nh, TAG_END());
122 return 0;
123 case nua_callstate_terminated:
124 return 1;
125 default:
126 return 0;
127 }
128 }
129
130
cancel_when_ringing(CONDITION_PARAMS)131 int cancel_when_ringing(CONDITION_PARAMS)
132 {
133 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
134 return 0;
135
136 save_event_in_list(ctx, event, ep, call);
137
138 switch (callstate(tags)) {
139 case nua_callstate_proceeding:
140 CANCEL(ep, call, nh, TAG_END());
141 return 0;
142 case nua_callstate_ready:
143 return 1;
144 case nua_callstate_terminated:
145 return 1;
146 default:
147 return 0;
148 }
149 }
150
151
alert_call(CONDITION_PARAMS)152 int alert_call(CONDITION_PARAMS)
153 {
154 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
155 return 0;
156
157 save_event_in_list(ctx, event, ep, call);
158
159 switch (callstate(tags)) {
160 case nua_callstate_received:
161 RESPOND(ep, call, nh, SIP_180_RINGING, TAG_END());
162 return 0;
163 case nua_callstate_terminated:
164 return 1;
165 default:
166 return 0;
167 }
168 }
169
170 int accept_after_183(CONDITION_PARAMS);
171
test_call_cancel(struct context * ctx)172 int test_call_cancel(struct context *ctx)
173 {
174 BEGIN();
175
176 struct endpoint *a = &ctx->a, *b = &ctx->b;
177 struct call *a_call = a->call, *b_call = b->call;
178 struct event *e;
179
180 a_call->sdp = "m=audio 5008 RTP/AVP 8";
181 b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
182
183 if (print_headings)
184 printf("TEST NUA-5.1.1: cancel call\n");
185
186 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
187
188 INVITE(a, a_call, a_call->nh,
189 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
190 SOATAG_USER_SDP_STR(a_call->sdp),
191 TAG_END());
192
193 run_ab_until(ctx, -1, cancel_when_calling, -1, until_terminated);
194
195 /* Client transitions:
196 INIT -(C1)-> CALLING: nua_invite(), nua_i_state, nua_cancel()
197 CALLING -(C6a)-> TERMINATED: nua_r_invite(487), nua_i_state
198 */
199 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
200 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
201 TEST_1(is_offer_sent(e->data->e_tags));
202 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_cancel);
203 TEST(e->data->e_status, 200);
204 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
205 TEST(e->data->e_status, 487);
206 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
207 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
208 TEST_1(!e->next);
209
210 /*
211 Server transitions:
212 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
213 RECEIVED -(S6a)--> TERMINATED: nua_i_cancel, nua_i_state
214 */
215 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
216 TEST(e->data->e_status, 100);
217 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
218 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
219 TEST_1(is_offer_recv(e->data->e_tags));
220 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_cancel);
221 TEST(e->data->e_status, 200);
222 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
223 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
224 TEST_1(!e->next);
225
226 free_events_in_list(ctx, a->events);
227 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
228
229 free_events_in_list(ctx, b->events);
230 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
231
232 if (print_headings)
233 printf("TEST NUA-5.1.1: PASSED\n");
234
235 /* ------------------------------------------------------------------------ */
236
237 if (print_headings)
238 printf("TEST NUA-5.1.2: cancel call (with nua_bye())\n");
239
240 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
241
242 INVITE(a, a_call, a_call->nh,
243 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
244 SIPTAG_SUBJECT_STR("TEST NUA-5.1.2"),
245 SOATAG_USER_SDP_STR(a_call->sdp),
246 TAG_END());
247
248 run_ab_until(ctx, -1, bye_when_calling, -1, until_terminated);
249
250 /* Client transitions:
251 INIT -(C1)-> CALLING: nua_invite(), nua_i_state, nua_cancel()
252 CALLING -(C6a)-> TERMINATED: nua_r_invite(487), nua_i_state
253 */
254 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
255 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
256 TEST_1(is_offer_sent(e->data->e_tags));
257 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_bye);
258 TEST(e->data->e_status, 200);
259 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
260 TEST(e->data->e_status, 487);
261 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
262 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
263 TEST_1(!e->next);
264
265 /*
266 Server transitions:
267 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
268 RECEIVED -(S6a)--> TERMINATED: nua_i_cancel, nua_i_state
269 */
270 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
271 TEST(e->data->e_status, 100);
272 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
273 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
274 TEST_1(is_offer_recv(e->data->e_tags));
275 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_cancel);
276 TEST(e->data->e_status, 200);
277 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
278 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
279 TEST_1(!e->next);
280
281 free_events_in_list(ctx, a->events);
282 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
283
284 free_events_in_list(ctx, b->events);
285 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
286
287 if (print_headings)
288 printf("TEST NUA-5.1.2: PASSED\n");
289
290 /* ----------------------------------------------------------------------- */
291
292 if (print_headings)
293 printf("TEST NUA-5.2.1: cancel call when ringing\n");
294
295 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
296
297 INVITE(a, a_call, a_call->nh,
298 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
299 SOATAG_USER_SDP_STR(a_call->sdp),
300 /*SIPTAG_REJECT_CONTACT_STR("*;audio=FALSE"),*/
301 TAG_END());
302
303 run_ab_until(ctx, -1, cancel_when_ringing, -1, alert_call);
304
305 /* Client transitions:
306 INIT -(C1)-> CALLING: nua_invite(), nua_i_state
307 CALLING -(C2)-> PROCEEDING: nua_r_invite(180, nua_i_state, nua_cancel()
308 PROCEEDING -(C6b)-> TERMINATED: nua_r_invite(487), nua_i_state
309 */
310 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
311 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
312 TEST_1(is_offer_sent(e->data->e_tags));
313 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
314 TEST(e->data->e_status, 180);
315 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
316 TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
317 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_cancel);
318 TEST(e->data->e_status, 200);
319 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
320 TEST(e->data->e_status, 487);
321 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
322 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
323 TEST_1(!e->next);
324
325 /*
326 Server transitions:
327 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
328 RECEIVED -(S2a)-> EARLY: nua_respond(180), nua_i_state
329 EARLY -(S6b)--> TERMINATED: nua_i_cancel, nua_i_state
330 */
331 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
332 TEST(e->data->e_status, 100);
333 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
334 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
335 TEST_1(is_offer_recv(e->data->e_tags));
336 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
337 TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
338 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_cancel);
339 TEST(e->data->e_status, 200);
340 /* Check for bug #1326727 */
341 TEST_1(e->data->e_msg);
342 #if 0
343 TEST_1(sip_object(e->data->e_msg)->sip_reject_contact);
344 TEST_1(sip_object(e->data->e_msg)->sip_reject_contact->cp_params &&
345 sip_object(e->data->e_msg)->sip_reject_contact->cp_params[0]);
346 TEST_S(sip_object(e->data->e_msg)->sip_reject_contact->cp_params[0],
347 "audio=FALSE");
348 #endif
349 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
350 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
351 TEST_1(!e->next);
352
353 free_events_in_list(ctx, a->events);
354 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
355
356 free_events_in_list(ctx, b->events);
357 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
358
359 if (print_headings)
360 printf("TEST NUA-5.2.1: PASSED\n");
361
362 /* ------------------------------------------------------------------------ */
363 if (print_headings)
364 printf("TEST NUA-5.2.2: CANCEL call when server waits for PRACK\n");
365
366 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
367
368 INVITE(a, a_call, a_call->nh,
369 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
370 SOATAG_USER_SDP_STR(a_call->sdp),
371 NUTAG_APPL_METHOD("PRACK"),
372 /*SIPTAG_REJECT_CONTACT_STR("*;audio=FALSE"),*/
373 TAG_END());
374
375 run_ab_until(ctx, -1, cancel_when_ringing, -1, accept_after_183);
376
377 free_events_in_list(ctx, a->events);
378 free_events_in_list(ctx, b->events);
379
380 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
381 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
382
383 if (print_headings)
384 printf("TEST NUA-5.2.2: PASSED\n");
385
386
387 END();
388 }
389
accept_after_183(CONDITION_PARAMS)390 int accept_after_183(CONDITION_PARAMS)
391 {
392 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
393 return 0;
394
395 save_event_in_list(ctx, event, ep, call);
396
397 switch (callstate(tags)) {
398 case nua_callstate_received:
399 RESPOND(ep, call, nh, SIP_183_SESSION_PROGRESS, TAG_END());
400 RESPOND(ep, call, nh, SIP_200_OK, TAG_END());
401 return 0;
402 case nua_callstate_terminated:
403 return 1;
404 default:
405 return 0;
406 }
407 }
408
409
410 /* ======================================================================== */
411 /* Destroy call handle */
412
destroy_when_calling(CONDITION_PARAMS)413 int destroy_when_calling(CONDITION_PARAMS)
414 {
415 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
416 return 0;
417
418 save_event_in_list(ctx, event, ep, call);
419
420 switch (callstate(tags)) {
421 case nua_callstate_calling:
422 DESTROY(ep, call, nh);
423 return 1;
424 default:
425 return 0;
426 }
427 }
428
destroy_when_completing(CONDITION_PARAMS)429 int destroy_when_completing(CONDITION_PARAMS)
430 {
431 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
432 return 0;
433
434 save_event_in_list(ctx, event, ep, call);
435
436 switch (callstate(tags)) {
437 case nua_callstate_completing:
438 DESTROY(ep, call, nh);
439 return 1;
440 case nua_callstate_ready:
441 return 1;
442 case nua_callstate_terminated:
443 if (call)
444 nua_handle_destroy(call->nh), call->nh = NULL;
445 return 1;
446 default:
447 return 0;
448 }
449 }
450
test_call_destroy_1(struct context * ctx)451 int test_call_destroy_1(struct context *ctx)
452 {
453 BEGIN();
454
455 struct endpoint *a = &ctx->a, *b = &ctx->b;
456 struct call *a_call = a->call, *b_call = b->call;
457 struct event *e;
458
459 if (print_headings)
460 printf("TEST NUA-5.3: destroy when calling\n");
461
462 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
463
464 INVITE(a, a_call, a_call->nh,
465 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
466 SOATAG_USER_SDP_STR(a_call->sdp),
467 TAG_END());
468
469 run_ab_until(ctx, -1, destroy_when_calling, -1, until_terminated);
470
471 /* Client transitions:
472 INIT -(C1)-> CALLING: nua_invite(), ...
473 */
474 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
475 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
476 TEST_1(is_offer_sent(e->data->e_tags));
477 TEST_1(!e->next);
478
479 free_events_in_list(ctx, a->events);
480 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
481
482 /*
483 Server transitions:
484 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
485 RECEIVED -(S6a)--> TERMINATED: nua_i_cancel, nua_i_state
486 */
487 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
488 TEST(e->data->e_status, 100);
489 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
490 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
491 TEST_1(is_offer_recv(e->data->e_tags));
492 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_cancel);
493 TEST(e->data->e_status, 200);
494 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
495 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
496 TEST_1(!e->next);
497
498 free_events_in_list(ctx, b->events);
499 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
500
501 if (print_headings)
502 printf("TEST NUA-5.3: PASSED\n");
503
504 END();
505 }
506
accept_until_terminated(CONDITION_PARAMS)507 int accept_until_terminated(CONDITION_PARAMS)
508 {
509 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
510 return 0;
511
512 save_event_in_list(ctx, event, ep, call);
513
514 switch (callstate(tags)) {
515 case nua_callstate_received:
516 RESPOND(ep, call, nh, SIP_180_RINGING, TAG_END());
517 return 0;
518 case nua_callstate_early:
519 RESPOND(ep, call, nh, SIP_200_OK,
520 TAG_IF(call->sdp, SOATAG_USER_SDP_STR(call->sdp)),
521 TAG_END());
522 return 0;
523 case nua_callstate_completed:
524 case nua_callstate_ready:
525 return 0;
526 case nua_callstate_terminated:
527 if (call)
528 nua_handle_destroy(call->nh), call->nh = NULL;
529 return 1;
530 default:
531 return 0;
532 }
533 }
534
test_call_destroy_2(struct context * ctx)535 int test_call_destroy_2(struct context *ctx)
536 {
537 BEGIN();
538
539 struct endpoint *a = &ctx->a, *b = &ctx->b;
540 struct call *a_call = a->call, *b_call = b->call;
541 struct event *e;
542
543 if (print_headings)
544 printf("TEST NUA-5.4: destroy when completing\n");
545
546 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
547
548 INVITE(a, a_call, a_call->nh,
549 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
550 NUTAG_AUTOACK(0),
551 SOATAG_USER_SDP_STR(a_call->sdp),
552 TAG_END());
553
554 run_ab_until(ctx, -1, destroy_when_completing, -1, accept_until_terminated);
555
556 /* Client transitions:
557 INIT -(C1)-> CALLING: nua_invite(), ...
558 */
559 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
560 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
561 TEST_1(is_offer_sent(e->data->e_tags));
562 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
563 TEST(e->data->e_status, 180);
564 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
565 TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
566 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
567 TEST(e->data->e_status, 200);
568 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
569 TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */
570 TEST_1(is_answer_recv(e->data->e_tags));
571 TEST_1(!e->next);
572
573 free_events_in_list(ctx, a->events);
574 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
575
576 /*
577 Server transitions:
578 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
579 RECEIVED -(S2a)-> EARLY: nua_respond(), nua_i_state
580 EARLY -(S3b)-> COMPLETED: nua_respond(), nua_i_state
581 COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
582 */
583 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
584 TEST(e->data->e_status, 100);
585 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
586 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
587 TEST_1(is_offer_recv(e->data->e_tags));
588 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
589 TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
590 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
591 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
592 TEST_1(is_answer_sent(e->data->e_tags));
593 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
594 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
595 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
596 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_bye);
597 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
598 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
599 TEST_1(!e->next);
600
601 free_events_in_list(ctx, b->events);
602 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
603
604 if (print_headings)
605 printf("TEST NUA-5.4: PASSED\n");
606
607 END();
608 }
609
destroy_when_early(CONDITION_PARAMS)610 int destroy_when_early(CONDITION_PARAMS)
611 {
612 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
613 return 0;
614
615 save_event_in_list(ctx, event, ep, call);
616
617 switch (callstate(tags)) {
618 case nua_callstate_received:
619 RESPOND(ep, call, nh, SIP_180_RINGING, TAG_END());
620 return 0;
621 case nua_callstate_early:
622 if (call)
623 DESTROY(ep, call, nh), call->nh = NULL;
624 return 1;
625 case nua_callstate_completed:
626 case nua_callstate_ready:
627 case nua_callstate_terminated:
628 if (call)
629 DESTROY(ep, call, nh), call->nh = NULL;
630 return 1;
631 default:
632 return 0;
633 }
634 }
635
test_call_destroy_3(struct context * ctx)636 int test_call_destroy_3(struct context *ctx)
637 {
638 BEGIN();
639
640 struct endpoint *a = &ctx->a, *b = &ctx->b;
641 struct call *a_call = a->call, *b_call = b->call;
642 struct event *e;
643
644 if (print_headings)
645 printf("TEST NUA-5.5: destroy when early\n");
646
647 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
648
649 INVITE(a, a_call, a_call->nh,
650 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
651 NUTAG_AUTOACK(0),
652 SOATAG_USER_SDP_STR(a_call->sdp),
653 TAG_END());
654
655 run_ab_until(ctx, -1, until_terminated, -1, destroy_when_early);
656
657 /* Client transitions:
658 INIT -(C1)-> CALLING: nua_invite(), ...
659 */
660 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
661 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
662 TEST_1(is_offer_sent(e->data->e_tags));
663 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
664 TEST(e->data->e_status, 180);
665 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
666 TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
667 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
668 TEST(e->data->e_status, 480);
669 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
670 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
671 TEST_1(!e->next);
672 TEST_1(!e->next);
673
674 free_events_in_list(ctx, a->events);
675 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
676
677 /*
678 Server transitions:
679 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
680 RECEIVED -(S2a)-> EARLY: nua_respond(), nua_i_state
681 EARLY -(S3b)-> COMPLETED: nua_respond(), nua_i_state ... DESTROY
682 */
683 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
684 TEST(e->data->e_status, 100);
685 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
686 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
687 TEST_1(is_offer_recv(e->data->e_tags));
688 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
689 TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
690 TEST_1(!e->next);
691
692 free_events_in_list(ctx, b->events);
693 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
694
695 if (print_headings)
696 printf("TEST NUA-5.5: PASSED\n");
697
698 END();
699 }
700
destroy_when_completed(CONDITION_PARAMS)701 int destroy_when_completed(CONDITION_PARAMS)
702 {
703 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
704 return 0;
705
706 save_event_in_list(ctx, event, ep, call);
707
708 switch (callstate(tags)) {
709 case nua_callstate_received:
710 RESPOND(ep, call, nh, SIP_180_RINGING, TAG_END());
711 return 0;
712 case nua_callstate_early:
713 RESPOND(ep, call, nh, SIP_200_OK,
714 TAG_IF(call->sdp, SOATAG_USER_SDP_STR(call->sdp)),
715 TAG_END());
716 return 0;
717 case nua_callstate_completed:
718 case nua_callstate_ready:
719 case nua_callstate_terminated:
720 if (call)
721 DESTROY(ep, call, nh), call->nh = NULL;
722 return 1;
723 default:
724 return 0;
725 }
726 }
727
test_call_destroy_4(struct context * ctx)728 int test_call_destroy_4(struct context *ctx)
729 {
730 BEGIN();
731
732 struct endpoint *a = &ctx->a, *b = &ctx->b;
733 struct call *a_call = a->call, *b_call = b->call;
734 struct event *e;
735
736 if (print_headings)
737 printf("TEST NUA-5.6: destroy when completed\n");
738
739 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
740
741 INVITE(a, a_call, a_call->nh,
742 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
743 NUTAG_AUTOACK(0),
744 SOATAG_USER_SDP_STR(a_call->sdp),
745 TAG_END());
746
747 run_ab_until(ctx, -1, until_terminated, -1, destroy_when_completed);
748
749 /* Client transitions:
750 INIT -(C1)-> CALLING: nua_invite(), ...
751 */
752 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
753 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
754 TEST_1(is_offer_sent(e->data->e_tags));
755 TEST_1(e = e->next); if (e->data->e_event == nua_r_invite) {
756 TEST_E(e->data->e_event, nua_r_invite);
757 TEST(e->data->e_status, 180);
758 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
759 TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
760 TEST_1(e = e->next);
761 }
762 if (e->data->e_event == nua_r_invite) {
763 TEST_E(e->data->e_event, nua_r_invite);
764 TEST(e->data->e_status, 200);
765 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
766 TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */
767 TEST_1(is_answer_recv(e->data->e_tags));
768 TEST_1(e = e->next);
769 }
770 TEST_E(e->data->e_event, nua_i_bye);
771 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
772 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
773
774 free_events_in_list(ctx, a->events);
775 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
776
777 /*
778 Server transitions:
779 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
780 RECEIVED -(S2a)-> EARLY: nua_respond(), nua_i_state
781 EARLY -(S3b)-> COMPLETED: nua_respond(), nua_i_state ... DESTROY
782 */
783 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
784 TEST(e->data->e_status, 100);
785 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
786 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
787 TEST_1(is_offer_recv(e->data->e_tags));
788 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
789 TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
790 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
791 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
792 TEST_1(is_answer_sent(e->data->e_tags));
793 TEST_1(!e->next);
794
795 free_events_in_list(ctx, b->events);
796 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
797
798 if (print_headings)
799 printf("TEST NUA-5.6: PASSED\n");
800
801 END();
802 }
803
804 /* Destroy when one INVITE is queued. */
test_call_destroy_5(struct context * ctx)805 int test_call_destroy_5(struct context *ctx)
806 {
807 BEGIN();
808
809 struct endpoint *a = &ctx->a, *b = &ctx->b;
810 struct call *a_call = a->call, *b_call = b->call;
811 struct event *e;
812
813 if (print_headings)
814 printf("TEST NUA-5.7: destroy when re-INVITE is queued\n");
815
816 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
817
818 INVITE(a, a_call, a_call->nh,
819 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
820 NUTAG_AUTOACK(0),
821 SOATAG_USER_SDP_STR(a_call->sdp),
822 TAG_END());
823
824 INVITE(a, a_call, a_call->nh, TAG_END());
825
826 run_ab_until(ctx, -1, until_terminated, -1, destroy_when_completed);
827
828 /* Client transitions:
829 INIT -(C1)-> CALLING: nua_invite(), ...
830 */
831 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
832 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
833 TEST_1(is_offer_sent(e->data->e_tags));
834 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
835 TEST(e->data->e_status, 180);
836 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
837 TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
838 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
839 TEST(e->data->e_status, 200);
840 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
841 TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */
842 TEST_1(is_answer_recv(e->data->e_tags));
843 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_bye);
844 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
845 TEST(e->data->e_status, 481);
846 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
847 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
848 TEST_1(!e->next);
849
850 free_events_in_list(ctx, a->events);
851 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
852
853 /*
854 Server transitions:
855 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
856 RECEIVED -(S2a)-> EARLY: nua_respond(), nua_i_state
857 EARLY -(S3b)-> COMPLETED: nua_respond(), nua_i_state ... DESTROY
858 */
859 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
860 TEST(e->data->e_status, 100);
861 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
862 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
863 TEST_1(is_offer_recv(e->data->e_tags));
864 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
865 TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
866 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
867 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
868 TEST_1(is_answer_sent(e->data->e_tags));
869 TEST_1(!e->next);
870
871 free_events_in_list(ctx, b->events);
872 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
873
874 if (print_headings)
875 printf("TEST NUA-5.7: PASSED\n");
876
877 END();
878 }
879
test_call_destroy(struct context * ctx)880 int test_call_destroy(struct context *ctx)
881 {
882 struct endpoint *a = &ctx->a, *b = &ctx->b;
883 struct call *a_call = a->call, *b_call = b->call;
884
885 a_call->sdp = "m=audio 5008 RTP/AVP 8";
886 b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
887
888 return
889 test_call_destroy_1(ctx) ||
890 test_call_destroy_2(ctx) ||
891 test_call_destroy_3(ctx) ||
892 test_call_destroy_4(ctx) ||
893 test_call_destroy_5(ctx);
894 }
895
896 /* ======================================================================== */
897
898 /* Early BYE
899
900 A B
901 |-------INVITE------>|
902 |<----100 Trying-----|
903 | |
904 |<----180 Ringing----|
905 | |
906 |--------BYE-------->|
907 |<------200 OK-------|
908 | |
909 |<-------487---------|
910 |--------ACK-------->|
911 | |
912 | |
913
914 Client transitions:
915 INIT -(C1)-> CALLING -(C2)-> PROCEEDING -(8)-> TERMINATING -> TERMINATED
916
917 Server transitions:
918 INIT -(S1)-> RECEIVED -(S2a)-> EARLY -(S8)-> TERMINATED
919
920 */
921
bye_when_ringing(CONDITION_PARAMS)922 int bye_when_ringing(CONDITION_PARAMS)
923 {
924 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
925 return 0;
926
927 save_event_in_list(ctx, event, ep, call);
928
929 switch (callstate(tags)) {
930 case nua_callstate_proceeding:
931 BYE(ep, call, nh, TAG_END());
932 return 0;
933 case nua_callstate_terminated:
934 return 1;
935 default:
936 return 0;
937 }
938 }
939
940 int bye_when_completing(CONDITION_PARAMS);
941
942 static int ack_sent = 0;
943
count_acks(void * arg,void * message,size_t len)944 size_t count_acks(void *arg, void *message, size_t len)
945 {
946 (void)arg;
947
948 if (su_casenmatch(message, "ACK sip:", 8))
949 ack_sent++;
950
951 return len;
952 }
953
test_bye_before_200(struct context * ctx)954 int test_bye_before_200(struct context *ctx)
955 {
956 BEGIN();
957 struct endpoint *a = &ctx->a, *b = &ctx->b;
958 struct call *a_call = a->call, *b_call = b->call;
959 struct event *e;
960
961 a_call->sdp = "m=audio 5008 RTP/AVP 8";
962 b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
963
964 if (print_headings)
965 printf("TEST NUA-6.1: BYE call when ringing\n");
966
967 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
968
969 INVITE(a, a_call, a_call->nh,
970 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
971 SOATAG_USER_SDP_STR(a_call->sdp),
972 TAG_END());
973
974 run_ab_until(ctx, -1, bye_when_ringing, -1, alert_call);
975
976 /* Client transitions:
977 INIT -(C1)-> CALLING: nua_invite(), nua_i_state
978 CALLING -(C2)-> PROCEEDING: nua_r_invite(180, nua_i_state, nua_cancel()
979 PROCEEDING -(C6b)-> TERMINATED: nua_r_invite(487), nua_i_state
980 */
981 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
982 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
983 TEST_1(is_offer_sent(e->data->e_tags));
984 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
985 TEST(e->data->e_status, 180);
986 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
987 TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
988 TEST_1(e = e->next);
989 if (e->data->e_event == nua_r_bye) {
990 /* We might receive this before or after response to INVITE */
991 /* If afterwards, it will come after nua_i_state and we just ignore it */
992 TEST_E(e->data->e_event, nua_r_bye); TEST(e->data->e_status, 200);
993 TEST_1(e->data->e_msg);
994 /* Forking has not been enabled, so this should be actually a CANCEL */
995 TEST(sip_object(e->data->e_msg)->sip_cseq->cs_method, sip_method_cancel);
996 TEST_1(e = e->next);
997 }
998 TEST_E(e->data->e_event, nua_r_invite); TEST(e->data->e_status, 487);
999 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1000 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
1001 TEST_1(!e->next);
1002
1003 /*
1004 Server transitions:
1005 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
1006 RECEIVED -(S2a)-> EARLY: nua_respond(180), nua_i_state
1007 EARLY -(S6b)--> TERMINATED: nua_i_cancel, nua_i_state
1008 */
1009 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
1010 TEST(e->data->e_status, 100);
1011 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1012 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
1013 TEST_1(is_offer_recv(e->data->e_tags));
1014 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1015 TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
1016 /* Forking has not been enabled, so this should be actually a CANCEL */
1017 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_cancel);
1018 TEST(e->data->e_status, 200);
1019 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1020 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
1021 TEST_1(!e->next);
1022
1023 free_events_in_list(ctx, a->events);
1024 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
1025
1026 free_events_in_list(ctx, b->events);
1027 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
1028
1029 if (print_headings)
1030 printf("TEST NUA-6.1: PASSED\n");
1031
1032 END();
1033 }
1034
1035
bye_when_completing(CONDITION_PARAMS)1036 int bye_when_completing(CONDITION_PARAMS)
1037 {
1038 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
1039 return 0;
1040
1041 save_event_in_list(ctx, event, ep, call);
1042
1043 switch (callstate(tags)) {
1044 case nua_callstate_completing:
1045 ack_sent = 0;
1046 BYE(ep, call, nh, TAG_END());
1047 return 0;
1048 case nua_callstate_terminated:
1049 return 1;
1050 default:
1051 return 0;
1052 }
1053 }
1054
1055
test_bye_before_ack(struct context * ctx)1056 int test_bye_before_ack(struct context *ctx)
1057 {
1058 BEGIN();
1059 struct endpoint *a = &ctx->a, *b = &ctx->b;
1060 struct call *a_call = a->call, *b_call = b->call;
1061 struct event *e;
1062 struct nat_filter *f = NULL;
1063
1064 a_call->sdp = "m=audio 5008 RTP/AVP 8";
1065 b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
1066
1067 /* Early BYE 2
1068
1069 A B
1070 |-------INVITE------>|
1071 |<----100 Trying-----|
1072 | |
1073 |<----180 Ringing----|
1074 |<-------200---------|
1075 | |
1076 |--------BYE-------->|
1077 |<------200 OK-------|
1078 |--------ACK-------->|
1079 | |
1080 | |
1081 */
1082 if (print_headings)
1083 printf("TEST NUA-6.2: BYE call when completing\n");
1084
1085 if (ctx->nat)
1086 TEST_1(f = test_nat_add_filter(ctx->nat, count_acks, NULL, nat_outbound));
1087 ack_sent = 0;
1088
1089 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
1090
1091 INVITE(a, a_call, a_call->nh,
1092 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
1093 SOATAG_USER_SDP_STR(a_call->sdp),
1094 NUTAG_AUTOACK(0),
1095 TAG_END());
1096
1097 run_ab_until(ctx, -1, bye_when_completing, -1, accept_until_terminated);
1098
1099 /* Client transitions:
1100 INIT -(C1)-> CALLING: nua_invite(), nua_i_state
1101 CALLING -(C2)-> PROCEEDING: nua_r_invite(180, nua_i_state, nua_cancel()
1102 PROCEEDING -(C6b)-> TERMINATED: nua_r_invite(487), nua_i_state
1103 */
1104 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
1105 TEST(callstate(e->data->e_tags), nua_callstate_calling);
1106 TEST_1(is_offer_sent(e->data->e_tags));
1107
1108 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
1109 TEST(e->data->e_status, 180);
1110 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1111 TEST(callstate(e->data->e_tags), nua_callstate_proceeding);
1112
1113 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
1114 TEST(e->data->e_status, 200);
1115 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1116 TEST(callstate(e->data->e_tags), nua_callstate_completing);
1117 TEST_1(e = e->next);
1118
1119 TEST_E(e->data->e_event, nua_r_bye); TEST(e->data->e_status, 200);
1120 TEST_1(e->data->e_msg);
1121 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1122 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
1123 TEST_1(!e->next);
1124
1125 if (ctx->nat) {
1126 while (ack_sent == 0)
1127 su_root_step(ctx->root, 100);
1128 TEST_1(ack_sent > 0);
1129 TEST_1(test_nat_remove_filter(ctx->nat, f) == 0);
1130 }
1131
1132 /*
1133 Server transitions:
1134 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
1135 RECEIVED -(S2a)-> EARLY: nua_respond(180), nua_i_state
1136 EARLY -(S6b)--> TERMINATED: nua_i_bye, nua_i_state
1137 */
1138 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
1139 TEST(e->data->e_status, 100);
1140 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1141 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
1142 TEST_1(is_offer_recv(e->data->e_tags));
1143 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1144 TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
1145 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1146 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
1147 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_bye);
1148 TEST(e->data->e_status, 200);
1149 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1150 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
1151 TEST_1(!e->next);
1152
1153 free_events_in_list(ctx, a->events);
1154 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
1155
1156 free_events_in_list(ctx, b->events);
1157 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
1158
1159 if (print_headings)
1160 printf("TEST NUA-6.2: PASSED\n");
1161
1162 END();
1163 }
1164
1165 int reject_reinvite_401(CONDITION_PARAMS);
1166
test_bye_after_receiving_401(struct context * ctx)1167 int test_bye_after_receiving_401(struct context *ctx)
1168 {
1169 BEGIN();
1170 struct endpoint *a = &ctx->a, *b = &ctx->b;
1171 struct call *a_call = a->call, *b_call = b->call;
1172 struct event *e;
1173
1174 a_call->sdp = "m=audio 5008 RTP/AVP 8";
1175 b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
1176
1177 /* BYE after receiving 401
1178
1179 A B
1180 |-------INVITE------>|
1181 |<----100 Trying-----|
1182 | |
1183 |<----180 Ringing----|
1184 |<-------200---------|
1185 |--------ACK-------->|
1186 | |
1187 |<------INVITE-------|
1188 |--------401-------->|
1189 |<--------ACK--------|
1190 | |
1191 |<--------BYE--------|
1192 |------200 OK------->|
1193 | |
1194 */
1195 if (print_headings)
1196 printf("TEST NUA-6.3: BYE after receiving 401\n");
1197
1198 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
1199
1200 INVITE(a, a_call, a_call->nh,
1201 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
1202 SIPTAG_SUBJECT_STR("NUA-6.3"),
1203 SOATAG_USER_SDP_STR(a_call->sdp),
1204 NUTAG_AUTOANSWER(0),
1205 TAG_END());
1206
1207 run_ab_until(ctx, -1, until_ready, -1, accept_call);
1208
1209 free_events_in_list(ctx, a->events);
1210
1211 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
1212 free_events_in_list(ctx, b->events);
1213
1214 /* re-INVITE A. */
1215 INVITE(b, b_call, b_call->nh,
1216 SIPTAG_SUBJECT_STR("NUA-6.3 re-INVITE"),
1217 TAG_END());
1218 run_ab_until(ctx, -1, reject_reinvite_401, -1, save_until_final_response);
1219
1220 TEST_1(nua_handle_has_active_call(a_call->nh));
1221 TEST_1(nua_handle_has_active_call(b_call->nh));
1222
1223 free_events_in_list(ctx, a->events);
1224 free_events_in_list(ctx, b->events);
1225
1226 BYE(b, b_call, b_call->nh, TAG_END());
1227
1228 run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
1229
1230 free_events_in_list(ctx, a->events);
1231 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
1232
1233 free_events_in_list(ctx, b->events);
1234 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
1235
1236 if (print_headings)
1237 printf("TEST NUA-6.3: PASSED\n");
1238
1239 END();
1240 }
1241
test_bye_after_sending_401(struct context * ctx)1242 int test_bye_after_sending_401(struct context *ctx)
1243 {
1244 BEGIN();
1245 struct endpoint *a = &ctx->a, *b = &ctx->b;
1246 struct call *a_call = a->call, *b_call = b->call;
1247 struct event *e;
1248
1249 a_call->sdp = "m=audio 5008 RTP/AVP 8";
1250 b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
1251
1252 /* BYE after sending 401
1253
1254 A B
1255 |-------INVITE------>|
1256 |<----100 Trying-----|
1257 | |
1258 |<----180 Ringing----|
1259 |<-------200---------|
1260 |--------ACK-------->|
1261 | |
1262 |<------INVITE-------|
1263 |--------401-------->|
1264 |<--------ACK--------|
1265 | |
1266 |--------BYE-------->|
1267 |<------200 OK-------|
1268 | |
1269 */
1270 if (print_headings)
1271 printf("TEST NUA-6.4.1: BYE after sending 401\n");
1272
1273 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
1274
1275 INVITE(a, a_call, a_call->nh,
1276 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
1277 SIPTAG_SUBJECT_STR("NUA-6.4.1"),
1278 SOATAG_USER_SDP_STR(a_call->sdp),
1279 NUTAG_AUTOANSWER(0),
1280 TAG_END());
1281
1282 run_ab_until(ctx, -1, until_ready, -1, accept_call);
1283
1284 free_events_in_list(ctx, a->events);
1285
1286 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
1287 free_events_in_list(ctx, b->events);
1288
1289 /* re-INVITE A. */
1290 INVITE(b, b_call, b_call->nh,
1291 SIPTAG_SUBJECT_STR("NUA-6.4.1 re-INVITE"),
1292 TAG_END());
1293 run_ab_until(ctx, -1, reject_reinvite_401, -1, save_until_final_response);
1294
1295 TEST_1(nua_handle_has_active_call(a_call->nh));
1296 TEST_1(nua_handle_has_active_call(b_call->nh));
1297
1298 free_events_in_list(ctx, a->events);
1299 free_events_in_list(ctx, b->events);
1300
1301 BYE(a, a_call, a_call->nh, TAG_END());
1302
1303 run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
1304
1305 free_events_in_list(ctx, a->events);
1306 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
1307
1308 free_events_in_list(ctx, b->events);
1309 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
1310
1311 if (print_headings)
1312 printf("TEST NUA-6.4.1: PASSED\n");
1313
1314 END();
1315 }
1316
test_bye_after_receiving_401_to_update(struct context * ctx)1317 int test_bye_after_receiving_401_to_update(struct context *ctx)
1318 {
1319 BEGIN();
1320 struct endpoint *a = &ctx->a, *b = &ctx->b;
1321 struct call *a_call = a->call, *b_call = b->call;
1322 struct event *e;
1323
1324 a_call->sdp = "m=audio 5008 RTP/AVP 8";
1325 b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
1326
1327 /* BYE after receiving 401
1328
1329 A B
1330 |-------INVITE------>|
1331 |<----100 Trying-----|
1332 | |
1333 |<----180 Ringing----|
1334 |<-------200---------|
1335 |--------ACK-------->|
1336 | |
1337 |<------UPDATE-------|
1338 |--------401-------->|
1339 | |
1340 |<--------BYE--------|
1341 |------200 OK------->|
1342 | |
1343 */
1344 if (print_headings)
1345 printf("TEST NUA-6.4.2: BYE after receiving 401 to UPDATE\n");
1346
1347 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
1348
1349 INVITE(a, a_call, a_call->nh,
1350 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
1351 SIPTAG_SUBJECT_STR("NUA-6.4.2"),
1352 SOATAG_USER_SDP_STR(a_call->sdp),
1353 NUTAG_AUTOANSWER(0),
1354 NUTAG_APPL_METHOD("UPDATE"),
1355 TAG_END());
1356
1357 run_ab_until(ctx, -1, until_ready, -1, accept_call);
1358
1359 free_events_in_list(ctx, a->events);
1360
1361 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
1362 free_events_in_list(ctx, b->events);
1363
1364 /* UPDATE A. */
1365 UPDATE(b, b_call, b_call->nh,
1366 SIPTAG_SUBJECT_STR("NUA-6.4.2 UPDATE"),
1367 TAG_END());
1368 BYE(b, b_call, b_call->nh, TAG_END()); /* Queued until nua_authenticate */
1369 run_ab_until(ctx, -1, reject_reinvite_401, -1, save_until_final_response);
1370
1371 TEST_1(nua_handle_has_active_call(a_call->nh));
1372 TEST_1(nua_handle_has_active_call(b_call->nh));
1373
1374 free_events_in_list(ctx, a->events);
1375 free_events_in_list(ctx, b->events);
1376
1377 AUTHENTICATE(b, b_call, b_call->nh, TAG_END());
1378
1379 run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
1380
1381 free_events_in_list(ctx, a->events);
1382 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
1383
1384 free_events_in_list(ctx, b->events);
1385 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
1386
1387 if (print_headings)
1388 printf("TEST NUA-6.4.2: PASSED\n");
1389
1390 END();
1391 }
1392
reject_reinvite_401(CONDITION_PARAMS)1393 int reject_reinvite_401(CONDITION_PARAMS)
1394 {
1395 void *request = nua_current_request(nua);
1396
1397 save_event_in_list(ctx, event, ep, call);
1398
1399 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
1400 return 0;
1401
1402 if (status < 200 && (event == nua_i_invite || event == nua_i_update)) {
1403 RESPOND(ep, call, nh, SIP_401_UNAUTHORIZED,
1404 NUTAG_WITH(request),
1405 SIPTAG_WWW_AUTHENTICATE_STR("Digest realm=\"test_nua\", "
1406 "nonce=\"nsdhfuds\", algorithm=MD5, "
1407 "qop=\"auth\""),
1408 TAG_END());
1409 return 0;
1410 }
1411
1412 if (event == nua_i_state) switch (callstate(tags)) {
1413 case nua_callstate_ready:
1414 return 1;
1415 case nua_callstate_terminated:
1416 if (call)
1417 nua_handle_destroy(call->nh), call->nh = NULL;
1418 return 1;
1419 default:
1420 return 0;
1421 }
1422
1423 return 0;
1424 }
1425
test_bye_with_407(struct context * ctx)1426 int test_bye_with_407(struct context *ctx)
1427 {
1428 BEGIN();
1429 struct endpoint *a = &ctx->a, *c = &ctx->c;
1430 struct call *a_call = a->call, *c_call = c->call;
1431 struct event *e;
1432
1433 a_call->sdp = "m=audio 5008 RTP/AVP 8";
1434 c_call->sdp = "m=audio 5010 RTP/AVP 0 8";
1435
1436 if (!ctx->proxy_tests)
1437 return 0;
1438
1439 /* BYE after receiving 401
1440
1441 A C
1442 |-------INVITE------>|
1443 |<----100 Trying-----|
1444 | |
1445 |<----180 Ringing----|
1446 |<-------200---------|
1447 |--------ACK-------->|
1448 | |
1449 | |<----BYE----|
1450 | |-----407--->|
1451 |<-------BYE---------|
1452 |--------200-------->|
1453 | |
1454 */
1455 if (print_headings)
1456 printf("TEST NUA-6.4.5: BYE with 407\n");
1457
1458 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(c->to), TAG_END()));
1459
1460 INVITE(a, a_call, a_call->nh,
1461 TAG_IF(!ctx->proxy_tests, NUTAG_URL(c->contact->m_url)),
1462 SIPTAG_SUBJECT_STR("NUA-6.4.2"),
1463 SOATAG_USER_SDP_STR(a_call->sdp),
1464 NUTAG_AUTOANSWER(0),
1465 NUTAG_APPL_METHOD("UPDATE"),
1466 TAG_END());
1467
1468 run_abc_until(ctx, -1, until_ready, -1, NULL, -1, accept_call);
1469
1470 free_events_in_list(ctx, a->events);
1471
1472 TEST_1(e = c->events->head); TEST_E(e->data->e_event, nua_i_invite);
1473 free_events_in_list(ctx, c->events);
1474
1475 BYE(c, c_call, c_call->nh,
1476 TAG_END());
1477 run_c_until(ctx, -1, save_until_final_response);
1478
1479 TEST_1(nua_handle_has_active_call(a_call->nh));
1480 TEST_1(nua_handle_has_active_call(c_call->nh));
1481
1482 free_events_in_list(ctx, a->events);
1483 free_events_in_list(ctx, c->events);
1484
1485 AUTHENTICATE(c, c_call, c_call->nh,
1486 NUTAG_AUTH("Digest:\"test-proxy\":charlie:secret"), TAG_END());
1487
1488 run_abc_until(ctx, -1, until_terminated, -1, NULL, -1, until_terminated);
1489
1490 free_events_in_list(ctx, a->events);
1491 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
1492
1493 free_events_in_list(ctx, c->events);
1494 nua_handle_destroy(c_call->nh), c_call->nh = NULL;
1495
1496 if (print_headings)
1497 printf("TEST NUA-6.4.5: PASSED\n");
1498
1499 END();
1500 }
1501
test_bye_to_invalid_contact(struct context * ctx)1502 int test_bye_to_invalid_contact(struct context *ctx)
1503 {
1504 BEGIN();
1505 struct endpoint *a = &ctx->a, *b = &ctx->b;
1506 struct call *a_call = a->call, *b_call = b->call;
1507 struct event *e;
1508 sip_t *sip = NULL;
1509
1510 int seen_401;
1511
1512 a_call->sdp = "m=audio 5008 RTP/AVP 8";
1513 b_call->sdp = "m=audio 5010 RTP/AVP 0 8";
1514
1515 /* Bad Contact URI
1516
1517 A B
1518 |-------INVITE------>|
1519 |<----100 Trying-----|
1520 | |
1521 |<----180 Ringing----|
1522 |<-------200---------|
1523 | |
1524 |--------ACK-------->|
1525 | |
1526 |<-------BYE---------|
1527 |--------400-------->|
1528 | |
1529 |--------BYE-------->|
1530 |<------200 OK-------|
1531 | |
1532 */
1533 if (print_headings)
1534 printf("TEST NUA-6.4.3: Test dialog with bad Contact info\n");
1535
1536 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
1537
1538 INVITE(a, a_call, a_call->nh,
1539 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
1540 SOATAG_USER_SDP_STR(a_call->sdp),
1541 SIPTAG_CONTACT(NULL),
1542 SIPTAG_HEADER_STR("Contact: <<sip:xyzzy@com.invalid>"),
1543 TAG_END());
1544
1545 run_ab_until(ctx, -1, until_ready, -1, accept_call);
1546
1547 /* Client transitions:
1548 INIT -(C1)-> CALLING: nua_invite(), nua_i_state
1549 CALLING -(C2)-> PROCEEDING: nua_r_invite(180, nua_i_state, nua_cancel()
1550 PROCEEDING -(C6b)-> TERMINATED: nua_r_invite(487), nua_i_state
1551 */
1552 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
1553 TEST(callstate(e->data->e_tags), nua_callstate_calling);
1554 TEST_1(is_offer_sent(e->data->e_tags));
1555
1556 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
1557 TEST(e->data->e_status, 180);
1558 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1559 TEST(callstate(e->data->e_tags), nua_callstate_proceeding);
1560
1561 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
1562 TEST(e->data->e_status, 200);
1563 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1564 TEST(callstate(e->data->e_tags), nua_callstate_ready);
1565 TEST_1(!e->next);
1566
1567 /*
1568 Server transitions:
1569 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
1570 RECEIVED -(S2a)-> EARLY: nua_respond(180), nua_i_state
1571 EARLY -(S6b)--> TERMINATED: nua_i_cancel, nua_i_state
1572 */
1573 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
1574 TEST(e->data->e_status, 100);
1575 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1576 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
1577 TEST_1(is_offer_recv(e->data->e_tags));
1578 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1579 TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
1580 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1581 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
1582 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
1583 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1584 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
1585 TEST_1(!e->next);
1586
1587 free_events_in_list(ctx, a->events);
1588 free_events_in_list(ctx, b->events);
1589
1590 BYE(b, b_call, b_call->nh, TAG_END());
1591
1592 run_b_until(ctx, -1, until_terminated);
1593
1594 /* B transitions:
1595 READY --(T2)--> TERMINATING: nua_bye()
1596 TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
1597 */
1598 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_r_bye);
1599 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1600 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
1601
1602 TEST_1(!nua_handle_has_active_call(b_call->nh));
1603 TEST_1(nua_handle_has_active_call(a_call->nh));
1604
1605 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
1606 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
1607
1608 if (print_headings)
1609 printf("TEST NUA-6.4.3: PASSED\n");
1610
1611 if (!ctx->p) {
1612 free_events_in_list(ctx, b->events);
1613 return 0;
1614 }
1615
1616 if (print_headings)
1617 printf("TEST NUA-6.4.4: Wait for re-REGISTER after connection has been closed\n");
1618
1619 if (!e->next || (!e->next->next || !e->next->data->e_status != 200))
1620 /* B is supposed to re-register pretty soon, wait for re-registration */
1621 run_b_until(ctx, -1, save_until_final_response);
1622
1623 seen_401 = 0;
1624
1625 for (e = e->next; e; e = e->next) {
1626 TEST_E(e->data->e_event, nua_r_register);
1627 TEST_1(sip = sip_object(e->data->e_msg));
1628
1629 if (e->data->e_status == 200) {
1630 TEST(e->data->e_status, 200);
1631 TEST_1(seen_401);
1632 TEST_1(sip->sip_contact);
1633 }
1634 else if (sip->sip_status && sip->sip_status->st_status == 401) {
1635 seen_401 = 1;
1636 }
1637
1638 if (!e->next)
1639 break;
1640 }
1641 TEST_1(e);
1642 TEST_S(sip->sip_contact->m_expires, "3600");
1643 TEST_1(!e->next);
1644 free_events_in_list(ctx, b->events);
1645
1646 if (print_headings)
1647 printf("TEST NUA-6.4.4: PASSED\n");
1648
1649 END();
1650 }
1651
test_early_bye(struct context * ctx)1652 int test_early_bye(struct context *ctx)
1653 {
1654 return
1655 test_bye_with_407(ctx) ||
1656 test_bye_before_200(ctx) ||
1657 test_bye_before_ack(ctx) ||
1658 test_bye_after_receiving_401(ctx) ||
1659 test_bye_after_sending_401(ctx) ||
1660 test_bye_after_receiving_401_to_update(ctx) ||
1661 test_bye_to_invalid_contact(ctx) ||
1662 0;
1663 }
1664