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