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_call_hold.c
26 * @brief Test re-INVITE, call hold, un-hold.
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_call_hold"
44 #endif
45
46 int complete_call(CONDITION_PARAMS);
47 int until_complete(CONDITION_PARAMS);
48 int invite_responded(CONDITION_PARAMS);
49 static size_t remove_first_ack(void *_once, void *message, size_t len);
50
51 /* ======================================================================== */
52 /* test_call_hold message sequence looks like this:
53
54 A B
55 | |
56 |-------INVITE------>|
57 |<----100 Trying-----|
58 | |
59 |<----180 Ringing----|
60 | |
61 |<--------200--------|
62 |---------ACK------->|
63 : :
64 |--INVITE(sendonly)->|
65 |<---200(recvonly)---|
66 |---------ACK------->|
67 : :
68 |<-INVITE(inactive)--|
69 |----200(inactive)-->|
70 |<--------ACK--------|
71 : :
72 |--INVITE(recvonly)->|
73 |<---200(sendonly)---|
74 |---------ACK------->|
75 : :
76 |<-INVITE(sendrecv)--|
77 |----200(sendrecv)-->|
78 |<--------ACK--------|
79 : :
80 |--------INFO------->|
81 |<--------200--------|
82 : :
83 |---------BYE------->|
84 |<--------200--------|
85 */
86
test_call_hold(struct context * ctx)87 int test_call_hold(struct context *ctx)
88 {
89 BEGIN();
90
91 struct endpoint *a = &ctx->a, *b = &ctx->b;
92 struct call *a_call = a->call, *b_call = b->call;
93 struct event *e;
94 sip_t *sip;
95 int zero = 0;
96 struct nat_filter *f;
97
98 a_call->sdp =
99 "m=audio 5008 RTP/AVP 0 8\n"
100 "m=video 6008 RTP/AVP 30\n";
101 b_call->sdp =
102 "m=audio 5010 RTP/AVP 8\n"
103 "a=rtcp:5011\n"
104 "m=video 6010 RTP/AVP 30\n"
105 "a=rtcp:6011\n";
106
107 TEST_1(a_call->nh = nua_handle(a->nua, a_call, SIPTAG_TO(b->to), TAG_END()));
108 INVITE(a, a_call, a_call->nh,
109 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
110 SOATAG_USER_SDP_STR(a_call->sdp),
111 TAG_END());
112
113 run_ab_until(ctx, -1, until_ready, -1, accept_call);
114
115 /*
116 Client transitions:
117 INIT -(C1)-> CALLING: nua_invite(), nua_i_state
118 CALLING -(C2)-> PROCEEDING: nua_r_invite, nua_i_state
119 PROCEEDING -(C3+C4)-> READY: nua_r_invite, nua_i_state
120 */
121 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
122 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
123 TEST_1(is_offer_sent(e->data->e_tags));
124 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
125 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
126 TEST(callstate(e->data->e_tags), nua_callstate_proceeding); /* PROCEEDING */
127 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
128 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
129 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
130 TEST_1(is_answer_recv(e->data->e_tags));
131 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
132 TEST_1(!e->next);
133 free_events_in_list(ctx, a->events);
134
135 TEST_1(nua_handle_has_active_call(a_call->nh));
136 TEST_1(!nua_handle_has_call_on_hold(a_call->nh));
137
138 /*
139 Server transitions:
140 INIT -(S1)-> RECEIVED: nua_i_invite, nua_i_state
141 RECEIVED -(S2a)-> EARLY: nua_respond(), nua_i_state
142 EARLY -(S3b)-> COMPLETED: nua_respond(), nua_i_state
143 COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
144 */
145 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
146 TEST(e->data->e_status, 100);
147 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
148 TEST(callstate(e->data->e_tags), nua_callstate_received); /* RECEIVED */
149 TEST_1(is_offer_recv(e->data->e_tags));
150 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
151 TEST(callstate(e->data->e_tags), nua_callstate_early); /* EARLY */
152 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
153 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
154 TEST_1(is_answer_sent(e->data->e_tags));
155 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
156 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
157 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
158 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
159 TEST_1(!e->next);
160
161 TEST_1(nua_handle_has_active_call(b_call->nh));
162 TEST_1(!nua_handle_has_call_on_hold(b_call->nh));
163
164 free_events_in_list(ctx, b->events);
165
166 /*
167 : :
168 |--INVITE(sendonly)->|
169 |<---200(recvonly)---|
170 |---------ACK------->|
171 : :
172 */
173
174 if (print_headings)
175 printf("TEST NUA-7.1: put B on hold\n");
176
177 /* Put B on hold */
178 INVITE(a, a_call, a_call->nh, SOATAG_HOLD("audio"),
179 SIPTAG_SUBJECT_STR("hold b"),
180 TAG_END());
181 run_ab_until(ctx, -1, until_ready, -1, until_ready);
182
183 /* Client transitions:
184 READY -(C1)-> CALLING: nua_invite(), nua_i_state
185 CALLING -(C3a+C4)-> READY: nua_r_invite, nua_i_state
186 */
187 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
188 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
189 TEST_1(is_offer_sent(e->data->e_tags));
190 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
191 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
192 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
193 TEST_1(is_answer_recv(e->data->e_tags));
194 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDONLY);
195 TEST_1(!e->next);
196
197 TEST_1(nua_handle_has_active_call(a_call->nh));
198 TEST_1(nua_handle_has_call_on_hold(a_call->nh));
199
200 free_events_in_list(ctx, a->events);
201
202 /*
203 Server transitions:
204 READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
205 COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
206 */
207 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
208 TEST(e->data->e_status, 200);
209 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
210 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
211 TEST_1(is_answer_sent(e->data->e_tags));
212 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
213 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
214 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
215 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
216 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
217 TEST_1(!e->next);
218
219 TEST_1(nua_handle_has_active_call(b_call->nh));
220 TEST_1(!nua_handle_has_call_on_hold(b_call->nh));
221
222 free_events_in_list(ctx, b->events);
223
224 if (print_headings)
225 printf("TEST NUA-7.1: PASSED\n");
226
227 /* ------------------------------------------------------------------------ */
228 /*
229 : :
230 |<-INVITE(inactive)--|
231 |----200(inactive)-->|
232 |<--------ACK--------|
233 : :
234 */
235
236 if (print_headings)
237 printf("TEST NUA-7.2: put A on hold\n");
238
239 /* Put A on hold, too. */
240 INVITE(b, b_call, b_call->nh, SOATAG_HOLD("audio"),
241 SIPTAG_SUBJECT_STR("hold a"),
242 TAG_END());
243 run_ab_until(ctx, -1, until_ready, -1, until_ready);
244
245 /* Client transitions:
246 READY -(C1)-> CALLING: nua_invite(), nua_i_state
247 CALLING -(C3a+C4)-> READY: nua_r_invite, nua_i_state
248 */
249 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
250 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
251 TEST_1(is_offer_sent(e->data->e_tags));
252 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
253 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
254 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
255 TEST_1(is_answer_recv(e->data->e_tags));
256 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
257 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
258 TEST_1(!e->next);
259
260 TEST_1(nua_handle_has_active_call(b_call->nh));
261 TEST_1(nua_handle_has_call_on_hold(b_call->nh));
262
263 free_events_in_list(ctx, b->events);
264
265 /*
266 Server transitions:
267 READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
268 COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
269 */
270 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
271 TEST(e->data->e_status, 200);
272 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
273 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
274 TEST_1(is_answer_sent(e->data->e_tags));
275 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
276 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
277 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
278 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
279 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
280 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
281 TEST_1(!e->next);
282
283 TEST_1(nua_handle_has_active_call(a_call->nh));
284 TEST_1(nua_handle_has_call_on_hold(a_call->nh));
285
286 free_events_in_list(ctx, a->events);
287
288 if (print_headings)
289 printf("TEST NUA-7.2: PASSED\n");
290
291 /* ------------------------------------------------------------------------ */
292 /*
293 : :
294 |--INVITE(recvonly)->|
295 |<---200(sendonly)---|
296 |---------ACK------->|
297 : :
298 */
299
300 if (print_headings)
301 printf("TEST NUA-7.3: resume B\n");
302
303 /* Resume B from hold */
304 INVITE(a, a_call, a_call->nh, SOATAG_HOLD(NULL),
305 SIPTAG_SUBJECT_STR("resume b"),
306 TAG_END());
307 run_ab_until(ctx, -1, until_ready, -1, until_ready);
308
309 /* Client transitions:
310 READY -(C1)-> CALLING: nua_invite(), nua_i_state
311 CALLING -(C3a+C4)-> READY: nua_r_invite, nua_i_state
312 */
313 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_state);
314 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
315 TEST_1(is_offer_sent(e->data->e_tags));
316 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
317 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
318 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
319 TEST_1(is_answer_recv(e->data->e_tags));
320 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
321 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
322 TEST_1(!e->next);
323 free_events_in_list(ctx, a->events);
324
325 TEST_1(nua_handle_has_active_call(a_call->nh));
326 TEST_1(!nua_handle_has_call_on_hold(a_call->nh));
327
328 /*
329 Server transitions:
330 READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
331 COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
332 */
333 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
334 TEST(e->data->e_status, 200);
335 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
336 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
337 TEST_1(is_answer_sent(e->data->e_tags));
338 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDONLY);
339 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
340 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
341 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
342 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDONLY);
343 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
344 TEST_1(!e->next);
345
346 TEST_1(nua_handle_has_active_call(b_call->nh));
347 TEST_1(nua_handle_has_call_on_hold(b_call->nh));
348
349 free_events_in_list(ctx, b->events);
350
351 if (print_headings)
352 printf("TEST NUA-7.3: PASSED\n");
353
354 /* ------------------------------------------------------------------------ */
355 /*
356 : :
357 |<-INVITE(sendrecv)--|
358 |----200(sendrecv)-->|
359 |<--------ACK--------|
360 : :
361 */
362
363 if (print_headings)
364 printf("TEST NUA-7.4: resume A\n");
365
366 /* Resume A on hold, too. */
367 INVITE(b, b_call, b_call->nh, SOATAG_HOLD(""),
368 SIPTAG_SUBJECT_STR("TEST NUA-7.4: resume A"),
369 TAG_END());
370 run_ab_until(ctx, -1, until_ready, -1, until_ready);
371
372 /* Client transitions:
373 READY -(C1)-> CALLING: nua_invite(), nua_i_state
374 CALLING -(C3a+C4)-> READY: nua_r_invite, nua_i_state
375 */
376 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
377 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
378 TEST_1(is_offer_sent(e->data->e_tags));
379 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
380 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
381 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
382 TEST_1(is_answer_recv(e->data->e_tags));
383 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
384 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
385 TEST_1(!e->next);
386 free_events_in_list(ctx, b->events);
387
388 TEST_1(nua_handle_has_active_call(a_call->nh));
389 TEST_1(!nua_handle_has_call_on_hold(a_call->nh));
390
391 /*
392 Server transitions:
393 READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
394 COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
395 */
396 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
397 TEST(e->data->e_status, 200);
398 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
399 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
400 TEST_1(is_answer_sent(e->data->e_tags));
401 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
402 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
403 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
404 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
405 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
406 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
407 TEST_1(!e->next);
408
409 TEST_1(nua_handle_has_active_call(b_call->nh));
410 TEST_1(!nua_handle_has_call_on_hold(b_call->nh));
411
412 free_events_in_list(ctx, a->events);
413
414 if (print_headings)
415 printf("TEST NUA-7.4: PASSED\n");
416
417 /* ---------------------------------------------------------------------- */
418 /*
419 A B
420 |--------INFO------->|
421 |<--------200--------|
422 */
423 if (print_headings)
424 printf("TEST NUA-7.5: send INFO\n");
425
426 INFO(a, a_call, a_call->nh, TAG_END());
427 run_a_until(ctx, -1, save_until_final_response);
428 /* XXX - B should get a nua_i_info event with 405 */
429
430 /* A sent INFO, receives 405 */
431 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_info);
432 TEST(e->data->e_status, 405);
433 TEST_1(!e->next);
434 free_events_in_list(ctx, a->events);
435
436 #if 0 /* XXX */
437 /* B received INFO */
438 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_info);
439 TEST(e->data->e_status, 405);
440 TEST_1(!e->next);
441 free_events_in_list(ctx, b->events);
442 #endif
443
444 /* Add INFO to allowed methods */
445 nua_set_hparams(b_call->nh, NUTAG_ALLOW("INFO, PUBLISH"), TAG_END());
446 run_b_until(ctx, nua_r_set_params, until_final_response);
447
448 INFO(a, a_call, a_call->nh, TAG_END());
449 run_ab_until(ctx, -1, save_until_final_response, -1, save_until_received);
450
451 /* A sent INFO, receives 200 */
452 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_info);
453 TEST(e->data->e_status, 200);
454 TEST_1(!e->next);
455 free_events_in_list(ctx, a->events);
456
457 /* B received INFO */
458 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_info);
459 TEST(e->data->e_status, 200);
460 TEST_1(!e->next);
461 free_events_in_list(ctx, b->events);
462
463 if (print_headings)
464 printf("TEST NUA-7.5: PASSED\n");
465
466 /* ------------------------------------------------------------------------ */
467 /*
468 : :
469 |<------INVITE-------|
470 |--------200-------->|
471 |<--------ACK--------|
472 : :
473 */
474
475 if (print_headings)
476 printf("TEST NUA-7.6.1: re-INVITE without auto-ack\n");
477
478 /* Turn off auto-ack */
479 nua_set_hparams(b_call->nh, NUTAG_AUTOACK(0), TAG_END());
480 run_b_until(ctx, nua_r_set_params, until_final_response);
481
482 INVITE(b, b_call, b_call->nh, SOATAG_HOLD(""),
483 SIPTAG_SUBJECT_STR("TEST NUA-7.6: re-INVITE without auto-ack"),
484 TAG_END());
485 run_ab_until(ctx, -1, until_complete, -1, complete_call);
486
487 /* Client transitions:
488 READY -(C1)-> CALLING: nua_invite(), nua_i_state
489 CALLING -(C3a)-> COMPLETING: nua_r_invite, nua_i_state
490 COMPLETING -(C4)-> READY: nua_ack(), nua_i_state
491 */
492 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
493 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
494 TEST_1(is_offer_sent(e->data->e_tags));
495 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
496 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
497 TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */
498 TEST_1(is_answer_recv(e->data->e_tags));
499 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
500 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
501 TEST_1(!e->next);
502
503 free_events_in_list(ctx, b->events);
504
505 /*
506 Server transitions:
507 READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
508 COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
509 */
510 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
511 TEST(e->data->e_status, 200);
512 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
513 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
514 TEST_1(is_answer_sent(e->data->e_tags));
515 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
516 TEST_1(!e->next);
517 free_events_in_list(ctx, a->events);
518
519 ACK(b, b_call, b_call->nh, TAG_END());
520
521 run_ab_until(ctx, -1, until_ready, -1, until_ready);
522
523 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
524 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
525 TEST_1(!e->next);
526 free_events_in_list(ctx, b->events);
527
528 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_ack);
529 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
530 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
531 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
532 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_SENDRECV);
533 TEST_1(!e->next);
534 free_events_in_list(ctx, a->events);
535
536 if (print_headings)
537 printf("TEST NUA-7.6.1: PASSED\n");
538
539 /* ------------------------------------------------------------------------ */
540 /*
541 : :
542 |<------INVITE-------|
543 |--------200-------->|
544 |<--------ACK--------|
545 : :
546 */
547
548 if (ctx->proxy_tests && ctx->nat) {
549 if (print_headings)
550 printf("TEST NUA-7.6.2: almost overlapping re-INVITE\n");
551
552 /* Turn off auto-ack */
553 nua_set_hparams(b_call->nh, NUTAG_AUTOACK(0), TAG_END());
554 run_b_until(ctx, nua_r_set_params, until_final_response);
555
556 INVITE(b, b_call, b_call->nh, SOATAG_HOLD("#"),
557 SIPTAG_SUBJECT_STR("TEST NUA-7.6.2: re-INVITE"),
558 TAG_END());
559 run_ab_until(ctx, -1, until_complete, -1, complete_call);
560
561 /* Client transitions:
562 READY -(C1)-> CALLING: nua_invite(), nua_i_state
563 CALLING -(C3a)-> COMPLETING: nua_r_invite, nua_i_state
564 COMPLETING -(C4)-> READY: nua_ack(), nua_i_state
565 */
566 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
567 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
568 TEST_1(is_offer_sent(e->data->e_tags));
569 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
570 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
571 TEST(callstate(e->data->e_tags), nua_callstate_completing); /* COMPLETING */
572 TEST_1(is_answer_recv(e->data->e_tags));
573 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
574 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
575 TEST_1(!e->next);
576
577 free_events_in_list(ctx, b->events);
578
579 /*
580 Server transitions:
581 READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
582 COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
583 */
584 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_invite);
585 TEST(e->data->e_status, 200);
586 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
587 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
588 TEST_1(is_answer_sent(e->data->e_tags));
589 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
590 TEST_1(!e->next);
591 free_events_in_list(ctx, a->events);
592
593 f = test_nat_add_filter(ctx->nat, remove_first_ack, &zero, nat_inbound);
594
595 ACK(b, b_call, b_call->nh, TAG_END());
596 INVITE(b, b_call, b_call->nh, SOATAG_HOLD("*"),
597 SIPTAG_SUBJECT_STR("TEST NUA-7.6.2: almost overlapping re-INVITE"),
598 NUTAG_AUTOACK(1),
599 TAG_END());
600
601 run_ab_until(ctx, -1, until_ready, -1, invite_responded);
602
603 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
604 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
605 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
606 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
607 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
608 TEST(e->data->e_status, 100);
609 TEST_1(sip = sip_object(e->data->e_msg));
610 TEST_1(sip->sip_retry_after);
611
612 #if 1
613 if (e->next) {
614 free_events_in_list(ctx, b->events);
615 free_events_in_list(ctx, a->events);
616 goto passed; /* XXX - once in a while B *does* retry */
617 }
618 TEST_1(!e->next);
619 #endif
620 free_events_in_list(ctx, b->events);
621
622 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_i_ack);
623 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
624 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
625 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
626 TEST(video_activity(e->data->e_tags), SOA_ACTIVE_INACTIVE);
627 TEST_1(!e->next);
628 free_events_in_list(ctx, a->events);
629
630 test_nat_remove_filter(ctx->nat, f);
631
632 if (print_headings)
633 printf("TEST NUA-7.6.2: PASSED\n");
634 }
635
636
637 /* ---------------------------------------------------------------------- */
638 /*
639 A B
640 |---------BYE------->|
641 |<--------200--------|
642 */
643
644 if (print_headings)
645 printf("TEST NUA-7.6.3: terminate call\n");
646
647 BYE(a, a_call, a_call->nh, TAG_END());
648 run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
649
650 /*
651 Transitions of A:
652 READY --(T2)--> TERMINATING: nua_bye()
653 TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
654 */
655 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_bye);
656 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
657 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
658 TEST_1(!e->next);
659 free_events_in_list(ctx, a->events);
660
661 /* Transitions of B:
662 READY -(T1)-> TERMINATED: nua_i_bye, nua_i_state
663 */
664 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_bye);
665 TEST(e->data->e_status, 200);
666 if (ctx->proxy_tests && ctx->nat) {
667 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
668 TEST(e->data->e_status, 481);
669 }
670 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
671 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
672 TEST_1(!e->next);
673 free_events_in_list(ctx, b->events);
674
675 passed:
676
677 if (print_headings)
678 printf("TEST NUA-7.6.3: PASSED\n");
679
680 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
681 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
682
683 END();
684 }
685
686 /*
687 INVITE without auto-ack
688 X
689 | |
690 |-------INVITE------>|
691 |<--------200--------|
692 | |
693 |---------ACK------->|
694 */
complete_call(CONDITION_PARAMS)695 int complete_call(CONDITION_PARAMS)
696 {
697 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
698 return 0;
699
700 save_event_in_list(ctx, event, ep, call);
701
702 switch (callstate(tags)) {
703 case nua_callstate_completing:
704 return 1;
705 case nua_callstate_ready:
706 return 1;
707 case nua_callstate_terminated:
708 if (call)
709 nua_handle_destroy(call->nh), call->nh = NULL;
710 return 1;
711 default:
712 return 0;
713 }
714 }
715
716 /*
717 X INVITE
718 | |
719 |-------INVITE------>|
720 |<--------200--------|
721 */
until_complete(CONDITION_PARAMS)722 int until_complete(CONDITION_PARAMS)
723 {
724 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
725 return 0;
726
727 save_event_in_list(ctx, event, ep, call);
728
729 switch (callstate(tags)) {
730 case nua_callstate_completed:
731 case nua_callstate_ready:
732 return 1;
733 case nua_callstate_terminated:
734 if (call)
735 nua_handle_destroy(call->nh), call->nh = NULL;
736 return 1;
737 default:
738 return 0;
739 }
740 }
741
remove_first_ack(void * _once,void * message,size_t len)742 static size_t remove_first_ack(void *_once, void *message, size_t len)
743 {
744 int *once = _once;
745
746 if (*once)
747 return len;
748
749 if (strncmp("ACK ", message, 4) == 0) {
750 printf("FILTERING %.*s\n", strcspn(message, "\r\n"), (char *)message);
751 *once = 1;
752 return 0;
753 }
754
755 return len;
756 }
757
758 /* ======================================================================== */
759 /* test_reinvite message sequence looks like this:
760
761 A B
762 | |
763 |-------INVITE------>|
764 |<----100 Trying-----|
765 | |
766 |<----180 Ringing----|
767 | |
768 |<--------200--------|
769 |---------ACK------->|
770 : :
771 |<----re-INVITE------|
772 |<-------BYE---------|
773 |--------200-------->|
774 |-----487-INVITE---->|
775 |<--------ACK--------|
776 */
777
778 int accept_no_save(CONDITION_PARAMS);
779 int ringing_until_terminated(CONDITION_PARAMS);
780 int bye_when_ringing(CONDITION_PARAMS);
781
test_reinvite(struct context * ctx)782 int test_reinvite(struct context *ctx)
783 {
784 BEGIN();
785
786 struct endpoint *a = &ctx->a, *b = &ctx->b;
787 struct call *a_call = a->call, *b_call = b->call;
788
789 if (print_headings)
790 printf("TEST NUA-7.7: Test re-INVITE and BYE\n");
791
792 a_call->sdp = "m=audio 5008 RTP/AVP 0 8\n";
793 b_call->sdp = "m=audio 5010 RTP/AVP 8\n";
794
795 TEST_1(a_call->nh =
796 nua_handle(a->nua, a_call,
797 SIPTAG_FROM_STR("Alice <sip:alice@example.com>"),
798 SIPTAG_TO(b->to),
799 NUTAG_AUTOANSWER(0),
800 TAG_END()));
801 INVITE(a, a_call, a_call->nh,
802 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
803 SOATAG_USER_SDP_STR(a_call->sdp),
804 TAG_END());
805
806 run_ab_until(ctx, -1, accept_no_save, -1, accept_no_save);
807
808 TEST_1(nua_handle_has_active_call(a_call->nh));
809 TEST_1(nua_handle_has_active_call(b_call->nh));
810
811 free_events_in_list(ctx, a->events);
812 free_events_in_list(ctx, b->events);
813
814 /*
815 A B
816 |<----re-INVITE------|
817 |<------CANCEL-------|
818 |<-------BYE---------|
819 |-----200-CANCEL---->|
820 |------200-BYE------>|
821 |-----487-INVITE---->|
822 |<--------ACK--------|
823 */
824
825 /* re-INVITE A, send BYE after receiving 180 */
826 INVITE(b, b_call, b_call->nh,
827 SIPTAG_SUBJECT_STR("re-INVITE"),
828 TAG_END());
829 /* Run until both a and b has terminated their call */
830 run_ab_until(ctx, -1, ringing_until_terminated, -1, bye_when_ringing);
831
832 #if notyet
833 struct event *e;
834
835 /* XXX - check events later - now we are happy that calls get terminated */
836 /* Client events:
837 READY -(C1)-> CALLING: nua_invite(), nua_i_state
838 CALLING --(C2)--> PROCEEDING: nua_r_invite, nua_i_state, nua_bye()
839 PROCEEDING--((C3a+C4)-> READY: nua_r_invite, nua_i_state
840 READY --(T2)--> TERMINATING: nua_bye()
841 TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
842 */
843 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_state);
844 TEST(callstate(e->data->e_tags), nua_callstate_calling); /* CALLING */
845 TEST_1(is_offer_sent(e->data->e_tags));
846 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_r_invite);
847 TEST(e->data->e_status, 180);
848 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
849 TEST(callstate(e->data->e_tags), nua_callstate_terminating); /* READY */
850 /* Now we can receive events, in any possible order */
851 /* XXX */
852 TEST_1(e = e->next);
853
854 TEST_1(!nua_handle_has_active_call(a_call->nh));
855
856 /*
857 Server transitions:
858 READY --(T2)--> CTERMINATING: nua_bye()
859 TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
860 READY -(S3a)-> COMPLETED: nua_i_invite, <auto-answer>, nua_i_state
861 COMPLETED -(S4)-> READY: nua_i_ack, nua_i_state
862 */
863 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_invite);
864 TEST(e->data->e_status, 200);
865 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
866 TEST(callstate(e->data->e_tags), nua_callstate_completed); /* COMPLETED */
867 TEST_1(is_answer_sent(e->data->e_tags));
868 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
869 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_ack);
870 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
871 TEST(callstate(e->data->e_tags), nua_callstate_ready); /* READY */
872 TEST(audio_activity(e->data->e_tags), SOA_ACTIVE_RECVONLY);
873 TEST_1(!e->next);
874
875 TEST_1(nua_handle_has_active_call(b_call->nh));
876 TEST_1(!nua_handle_has_call_on_hold(b_call->nh));
877
878 #endif
879
880 if (print_headings)
881 printf("TEST NUA-7.7: PASSED\n");
882
883 free_events_in_list(ctx, a->events);
884 free_events_in_list(ctx, b->events);
885
886 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
887 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
888
889 END();
890 }
891
892 /*
893 Accept INVITE
894 X
895 | |
896 |-------INVITE------>|
897 |<--------200--------|
898 | |
899 |---------ACK------->|
900 */
accept_no_save(CONDITION_PARAMS)901 int accept_no_save(CONDITION_PARAMS)
902 {
903 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
904 return 0;
905
906 switch (callstate(tags)) {
907 case nua_callstate_received:
908 RESPOND(ep, call, nh, SIP_200_OK,
909 TAG_IF(call->sdp, SOATAG_USER_SDP_STR(call->sdp)),
910 TAG_END());
911 return 0;
912 case nua_callstate_ready:
913 return 1;
914 case nua_callstate_terminated:
915 if (call)
916 nua_handle_destroy(call->nh), call->nh = NULL;
917 return 1;
918 default:
919 return 0;
920 }
921 }
922
ringing_until_terminated(CONDITION_PARAMS)923 int ringing_until_terminated(CONDITION_PARAMS)
924 {
925 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
926 return 0;
927
928 save_event_in_list(ctx, event, ep, call);
929
930 switch (callstate(tags)) {
931 case nua_callstate_received:
932 RESPOND(ep, call, nh, SIP_180_RINGING, TAG_END());
933 return 0;
934 case nua_callstate_ready:
935 return 0;
936 case nua_callstate_terminated:
937 if (call)
938 nua_handle_destroy(call->nh), call->nh = NULL;
939 return 1;
940 default:
941 return 0;
942 }
943 }
944
945 /* ======================================================================== */
946
947 int accept_and_attempt_reinvite(CONDITION_PARAMS);
948 int until_ready2(CONDITION_PARAMS);
949
950 /* test_reinvite2 message sequence looks like this:
951
952 A B
953 | |
954 |-------INVITE------>|
955 |<----100 Trying-----|
956 | |
957 |<----180 Ringing----|
958 | |
959 | /-INVITE-|
960 | \---900->|
961 | |
962 |<--------200--------|
963 |---------ACK------->|
964 : :
965 : queue INVITE :
966 : :
967 |-----re-INVITE----->|
968 |<--------200--------|
969 |---------ACK------->|
970 |-----re-INVITE----->|
971 |<--------200--------|
972 |---------ACK------->|
973 : :
974 : glare :
975 : :
976 |-----re-INVITE----->|
977 |<----re-INVITE------|
978 |<--------491--------|
979 |---------491------->|
980 |---------ACK------->|
981 |<--------ACK--------|
982 : :
983 |---------BYE------->|
984 |<--------200--------|
985 */
986
test_reinvite2(struct context * ctx)987 int test_reinvite2(struct context *ctx)
988 {
989 BEGIN();
990
991 struct endpoint *a = &ctx->a, *b = &ctx->b;
992 struct call *a_call = a->call, *b_call = b->call;
993 struct event *e;
994
995 if (print_headings)
996 printf("TEST NUA-7.8.1: Test re-INVITE glare\n");
997
998 a_call->sdp = "m=audio 5008 RTP/AVP 0 8\n";
999 b_call->sdp = "m=audio 5010 RTP/AVP 8\n";
1000
1001 TEST_1(a_call->nh =
1002 nua_handle(a->nua, a_call,
1003 SIPTAG_FROM_STR("Alice <sip:alice@example.com>"),
1004 SIPTAG_TO(b->to),
1005 TAG_END()));
1006 INVITE(a, a_call, a_call->nh,
1007 TAG_IF(!ctx->proxy_tests, NUTAG_URL(b->contact->m_url)),
1008 SOATAG_USER_SDP_STR(a_call->sdp),
1009 TAG_END());
1010
1011 run_ab_until(ctx, -1, until_ready, -1, accept_and_attempt_reinvite);
1012
1013 TEST_1(nua_handle_has_active_call(a_call->nh));
1014 TEST_1(nua_handle_has_active_call(b_call->nh));
1015
1016 free_events_in_list(ctx, a->events);
1017 free_events_in_list(ctx, b->events);
1018
1019 /* Check that we can queue INVITEs */
1020 INVITE(a, a_call, a_call->nh, TAG_END());
1021 INVITE(a, a_call, a_call->nh, TAG_END());
1022
1023 run_ab_until(ctx, -1, until_ready2, -1, until_ready2);
1024
1025 free_events_in_list(ctx, a->events);
1026 free_events_in_list(ctx, b->events);
1027
1028 /* Check that INVITE glare works */
1029 INVITE(a, a_call, a_call->nh, TAG_END());
1030 INVITE(b, b_call, b_call->nh, TAG_END());
1031
1032 a->flags.n = 0, b->flags.n = 0;
1033 run_ab_until(ctx, -1, until_ready2, -1, until_ready2);
1034
1035 free_events_in_list(ctx, a->events);
1036 free_events_in_list(ctx, b->events);
1037
1038 if (print_headings)
1039 printf("TEST NUA-7.8.1: PASSED\n");
1040
1041
1042
1043 /* ---------------------------------------------------------------------- */
1044 /*
1045 A B
1046 |---------BYE------->|
1047 |<--------200--------|
1048 */
1049
1050 if (print_headings)
1051 printf("TEST NUA-7.8.2: terminate call\n");
1052
1053 BYE(a, a_call, a_call->nh, TAG_END());
1054 run_ab_until(ctx, -1, until_terminated, -1, until_terminated);
1055
1056 /*
1057 Transitions of A:
1058 READY --(T2)--> TERMINATING: nua_bye()
1059 TERMINATING --(T3)--> TERMINATED: nua_r_bye, nua_i_state
1060 */
1061 TEST_1(e = a->events->head); TEST_E(e->data->e_event, nua_r_bye);
1062 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1063 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
1064 TEST_1(!e->next);
1065 free_events_in_list(ctx, a->events);
1066
1067 /* Transitions of B:
1068 READY -(T1)-> TERMINATED: nua_i_bye, nua_i_state
1069 */
1070 TEST_1(e = b->events->head); TEST_E(e->data->e_event, nua_i_bye);
1071 TEST(e->data->e_status, 200);
1072 TEST_1(e = e->next); TEST_E(e->data->e_event, nua_i_state);
1073 TEST(callstate(e->data->e_tags), nua_callstate_terminated); /* TERMINATED */
1074 TEST_1(!e->next);
1075 free_events_in_list(ctx, b->events);
1076
1077 if (print_headings)
1078 printf("TEST NUA-7.8.2: PASSED\n");
1079
1080 nua_handle_destroy(a_call->nh), a_call->nh = NULL;
1081 nua_handle_destroy(b_call->nh), b_call->nh = NULL;
1082
1083 END();
1084 }
1085
accept_and_attempt_reinvite(CONDITION_PARAMS)1086 int accept_and_attempt_reinvite(CONDITION_PARAMS)
1087 {
1088 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
1089 return 0;
1090
1091 save_event_in_list(ctx, event, ep, call);
1092
1093 if (event == nua_i_prack) {
1094 INVITE(ep, call, nh, TAG_END());
1095 RESPOND(ep, call, nh, SIP_200_OK,
1096 TAG_IF(call->sdp, SOATAG_USER_SDP_STR(call->sdp)),
1097 TAG_END());
1098 }
1099 else switch (callstate(tags)) {
1100 case nua_callstate_received:
1101 RESPOND(ep, call, nh, SIP_180_RINGING,
1102 SIPTAG_REQUIRE_STR("100rel"),
1103 TAG_END());
1104 return 0;
1105 case nua_callstate_early:
1106 return 0;
1107 case nua_callstate_ready:
1108 return 1;
1109 case nua_callstate_terminated:
1110 if (call)
1111 nua_handle_destroy(call->nh), call->nh = NULL;
1112 return 1;
1113 default:
1114 return 0;
1115 }
1116 return 0;
1117 }
1118
1119 /*
1120 X INVITE
1121 | |
1122 |-------INVITE------>|
1123 |<--------200--------|
1124 |---------ACK------->|
1125 */
until_ready2(CONDITION_PARAMS)1126 int until_ready2(CONDITION_PARAMS)
1127 {
1128 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
1129 return 0;
1130
1131 save_event_in_list(ctx, event, ep, call);
1132
1133 if (event == nua_r_invite && status == 491) {
1134 if (ep == &ctx->a && ++ctx->b.flags.n >= 2) ctx->b.running = 0;
1135 if (ep == &ctx->b && ++ctx->a.flags.n >= 2) ctx->a.running = 0;
1136 }
1137
1138 switch (callstate(tags)) {
1139 case nua_callstate_ready:
1140 return ++ep->flags.n >= 2;
1141 case nua_callstate_terminated:
1142 if (call)
1143 nua_handle_destroy(call->nh), call->nh = NULL;
1144 return 1;
1145 default:
1146 return 0;
1147 }
1148 }
1149
invite_responded(CONDITION_PARAMS)1150 int invite_responded(CONDITION_PARAMS)
1151 {
1152 if (!(check_handle(ep, call, nh, SIP_500_INTERNAL_SERVER_ERROR)))
1153 return 0;
1154
1155 save_event_in_list(ctx, event, ep, call);
1156
1157 return event == nua_r_invite && status >= 100;
1158 }
1159
1160
test_reinvites(struct context * ctx)1161 int test_reinvites(struct context *ctx)
1162 {
1163 int retval = 0;
1164
1165 if (print_headings)
1166 printf("TEST NUA-7: Test call hold and re-INVITEs\n");
1167
1168 retval = test_call_hold(ctx);
1169
1170 if (retval == 0)
1171 retval = test_reinvite(ctx);
1172
1173 if (retval == 0)
1174 retval = test_reinvite2(ctx);
1175
1176 if (print_headings && retval == 0)
1177 printf("TEST NUA-7: PASSED\n");
1178
1179 return retval;
1180 }
1181