1 /**
2  * @file test/call.c  Baresip selftest -- call
3  *
4  * Copyright (C) 2010 - 2015 Creytiv.com
5  */
6 #include <string.h>
7 #include <re.h>
8 #include <rem.h>
9 #include <baresip.h>
10 #include "test.h"
11 
12 
13 #define MAGIC 0x7004ca11
14 
15 
16 enum behaviour {
17 	BEHAVIOUR_ANSWER = 0,
18 	BEHAVIOUR_PROGRESS,
19 	BEHAVIOUR_REJECT
20 };
21 
22 enum action {
23 	ACTION_RECANCEL = 0,
24 	ACTION_HANGUP_A,
25 	ACTION_HANGUP_B,
26 	ACTION_NOTHING
27 };
28 
29 struct agent {
30 	struct fixture *fix;    /* pointer to parent */
31 	struct agent *peer;
32 	struct ua *ua;
33 	uint16_t close_scode;
34 	bool failed;
35 
36 	unsigned n_incoming;
37 	unsigned n_progress;
38 	unsigned n_established;
39 	unsigned n_closed;
40 	unsigned n_dtmf_recv;
41 };
42 
43 struct fixture {
44 	uint32_t magic;
45 	struct agent a, b;
46 	struct sa laddr_sip;
47 	enum behaviour behaviour;
48 	enum action estab_action;
49 	char buri[256];
50 	int err;
51 	unsigned exp_estab;
52 	unsigned exp_closed;
53 };
54 
55 
56 #define fixture_init_prm(f, prm)					\
57 	memset(f, 0, sizeof(*f));					\
58 									\
59 	f->a.fix = f;							\
60 	f->b.fix = f;							\
61 									\
62 	err = ua_init("test", true, true, true, false);			\
63 	TEST_ERR(err);							\
64 									\
65 	f->magic = MAGIC;						\
66 	f->exp_estab = 1;						\
67 	f->exp_closed = 1;						\
68 	mock_aucodec_register();					\
69 									\
70 	err = ua_alloc(&f->a.ua,					\
71 		       "A <sip:a@127.0.0.1>;regint=0" prm);		\
72 	TEST_ERR(err);							\
73 	err = ua_alloc(&f->b.ua,					\
74 		       "B <sip:b@127.0.0.1>;regint=0" prm);		\
75 	TEST_ERR(err);							\
76 									\
77 	f->a.peer = &f->b;						\
78 	f->b.peer = &f->a;						\
79 									\
80 	err = uag_event_register(event_handler, f);			\
81 	TEST_ERR(err);							\
82 									\
83 	err = sip_transp_laddr(uag_sip(), &f->laddr_sip,		\
84 			       SIP_TRANSP_UDP, NULL);			\
85 	TEST_ERR(err);							\
86 									\
87 	re_snprintf(f->buri, sizeof(f->buri), "sip:b@%J", &f->laddr_sip);
88 
89 
90 #define fixture_init(f)				\
91 	fixture_init_prm((f), "");
92 
93 
94 #define fixture_close(f)			\
95 	mem_deref(f->b.ua);			\
96 	mem_deref(f->a.ua);			\
97 						\
98 	mock_aucodec_unregister();		\
99 						\
100 	uag_event_unregister(event_handler);	\
101 						\
102 	ua_stop_all(true);			\
103 	ua_close();
104 
105 #define fixture_abort(f, error)			\
106 	do {					\
107 		(f)->err = (error);		\
108 		re_cancel();			\
109 	} while (0)
110 
111 
event_handler(struct ua * ua,enum ua_event ev,struct call * call,const char * prm,void * arg)112 static void event_handler(struct ua *ua, enum ua_event ev,
113 			  struct call *call, const char *prm, void *arg)
114 {
115 	struct fixture *f = arg;
116 	struct agent *ag;
117 	int err = 0;
118 	(void)prm;
119 
120 #if 1
121 	info("test: [ %s ] event: %s (%s)\n",
122 		  ua_aor(ua), uag_event_str(ev), prm);
123 #endif
124 
125 	ASSERT_TRUE(f != NULL);
126 	ASSERT_EQ(MAGIC, f->magic);
127 
128 	if (ua == f->a.ua)
129 		ag = &f->a;
130 	else if (ua == f->b.ua)
131 		ag = &f->b;
132 	else {
133 		return;
134 	}
135 
136 	switch (ev) {
137 
138 	case UA_EVENT_CALL_INCOMING:
139 		++ag->n_incoming;
140 
141 		switch (f->behaviour) {
142 
143 		case BEHAVIOUR_ANSWER:
144 			err = ua_answer(ua, call);
145 			if (err) {
146 				warning("ua_answer failed (%m)\n", err);
147 				goto out;
148 			}
149 			break;
150 
151 		case BEHAVIOUR_PROGRESS:
152 			err = ua_progress(ua, call);
153 			if (err) {
154 				warning("ua_progress failed (%m)\n", err);
155 				goto out;
156 			}
157 			break;
158 
159 		case BEHAVIOUR_REJECT:
160 			ua_hangup(ua, call, 0, 0);
161 			call = NULL;
162 			ag->failed = true;
163 			break;
164 
165 		default:
166 			break;
167 		}
168 		break;
169 
170 	case UA_EVENT_CALL_PROGRESS:
171 		++ag->n_progress;
172 
173 		re_cancel();
174 		break;
175 
176 	case UA_EVENT_CALL_ESTABLISHED:
177 		++ag->n_established;
178 
179 		ASSERT_TRUE(str_isset(call_id(call)));
180 
181 		/* are both agents established? */
182 		if (ag->n_established >= f->exp_estab &&
183 		    ag->peer->n_established >= f->exp_estab) {
184 
185 			switch (f->estab_action) {
186 
187 			case ACTION_RECANCEL:
188 				re_cancel();
189 				break;
190 
191 			case ACTION_HANGUP_A:
192 				f->a.failed = true;
193 				ua_hangup(f->a.ua, NULL, 0, 0);
194 				break;
195 
196 			case ACTION_HANGUP_B:
197 				f->b.failed = true;
198 				ua_hangup(f->b.ua, NULL, 0, 0);
199 				break;
200 
201 			case ACTION_NOTHING:
202 				/* Do nothing, wait */
203 				break;
204 			}
205 		}
206 		break;
207 
208 	case UA_EVENT_CALL_CLOSED:
209 		++ag->n_closed;
210 
211 		ag->close_scode = call_scode(call);
212 
213 		if (ag->close_scode)
214 			ag->failed = true;
215 
216 		if (ag->n_closed >= f->exp_closed &&
217 		    ag->peer->n_closed >= f->exp_closed) {
218 
219 			re_cancel();
220 		}
221 		break;
222 
223 	default:
224 		break;
225 	}
226 
227 	if (ag->failed && ag->peer->failed) {
228 		info("test: re_cancel on call failed\n");
229 		re_cancel();
230 		return;
231 	}
232 
233  out:
234 	if (err) {
235 		warning("error in event-handler (%m)\n", err);
236 		f->err = err;
237 		re_cancel();
238 	}
239 }
240 
241 
test_call_answer(void)242 int test_call_answer(void)
243 {
244 	struct fixture fix, *f = &fix;
245 	int err = 0;
246 
247 	fixture_init(f);
248 
249 	f->behaviour = BEHAVIOUR_ANSWER;
250 
251 	/* Make a call from A to B */
252 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
253 	TEST_ERR(err);
254 
255 	/* run main-loop with timeout, wait for events */
256 	err = re_main_timeout(5000);
257 	TEST_ERR(err);
258 	TEST_ERR(fix.err);
259 
260 	ASSERT_EQ(0, fix.a.n_incoming);
261 	ASSERT_EQ(1, fix.a.n_established);
262 	ASSERT_EQ(0, fix.a.n_closed);
263 	ASSERT_EQ(0, fix.a.close_scode);
264 
265 	ASSERT_EQ(1, fix.b.n_incoming);
266 	ASSERT_EQ(1, fix.b.n_established);
267 	ASSERT_EQ(0, fix.b.n_closed);
268 
269  out:
270 	fixture_close(f);
271 
272 	return err;
273 }
274 
275 
test_call_reject(void)276 int test_call_reject(void)
277 {
278 	struct fixture fix, *f = &fix;
279 	int err = 0;
280 
281 	fixture_init(f);
282 
283 	f->behaviour = BEHAVIOUR_REJECT;
284 
285 	/* Make a call from A to B */
286 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
287 	TEST_ERR(err);
288 
289 	/* run main-loop with timeout, wait for events */
290 	err = re_main_timeout(5000);
291 	TEST_ERR(err);
292 	TEST_ERR(fix.err);
293 
294 	ASSERT_EQ(0, fix.a.n_incoming);
295 	ASSERT_EQ(0, fix.a.n_established);
296 	ASSERT_EQ(1, fix.a.n_closed);
297 
298 	ASSERT_EQ(1, fix.b.n_incoming);
299 	ASSERT_EQ(0, fix.b.n_established);
300 
301  out:
302 	fixture_close(f);
303 
304 	return err;
305 }
306 
307 
test_call_af_mismatch(void)308 int test_call_af_mismatch(void)
309 {
310 	struct fixture fix, *f = &fix;
311 	int err = 0;
312 
313 	fixture_init(f);
314 
315 	ua_set_media_af(f->a.ua, AF_INET6);
316 	ua_set_media_af(f->b.ua, AF_INET);
317 
318 	/* Make a call from A to B */
319 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
320 	TEST_ERR(err);
321 
322 	/* run main-loop with timeout, wait for events */
323 	err = re_main_timeout(5000);
324 	TEST_ERR(err);
325 	TEST_ERR(fix.err);
326 
327 	ASSERT_EQ(0, fix.a.n_incoming);
328 	ASSERT_EQ(0, fix.a.n_established);
329 	ASSERT_EQ(1, fix.a.n_closed);
330 	ASSERT_EQ(488, fix.a.close_scode);
331 
332 	ASSERT_EQ(0, fix.b.n_incoming);
333 	ASSERT_EQ(0, fix.b.n_established);
334 	ASSERT_EQ(1, fix.b.n_closed);
335 
336  out:
337 	fixture_close(f);
338 
339 	return err;
340 }
341 
342 
test_call_answer_hangup_a(void)343 int test_call_answer_hangup_a(void)
344 {
345 	struct fixture fix, *f = &fix;
346 	int err = 0;
347 
348 	fixture_init(f);
349 
350 	f->behaviour = BEHAVIOUR_ANSWER;
351 	f->estab_action = ACTION_HANGUP_A;
352 
353 	/* Make a call from A to B */
354 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
355 	TEST_ERR(err);
356 
357 	/* run main-loop with timeout, wait for events */
358 	err = re_main_timeout(5000);
359 	TEST_ERR(err);
360 	TEST_ERR(fix.err);
361 
362 	ASSERT_EQ(1, fix.a.n_established);
363 	ASSERT_EQ(1, fix.a.n_closed);
364 	ASSERT_EQ(0, fix.a.close_scode);
365 
366 	ASSERT_EQ(1, fix.b.n_established);
367 	ASSERT_EQ(1, fix.b.n_closed);
368 	ASSERT_EQ(0, fix.b.close_scode);
369 
370  out:
371 	fixture_close(f);
372 
373 	return err;
374 }
375 
376 
test_call_answer_hangup_b(void)377 int test_call_answer_hangup_b(void)
378 {
379 	struct fixture fix, *f = &fix;
380 	int err = 0;
381 
382 	fixture_init(f);
383 
384 	f->behaviour = BEHAVIOUR_ANSWER;
385 	f->estab_action = ACTION_HANGUP_B;
386 
387 	/* Make a call from A to B */
388 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
389 	TEST_ERR(err);
390 
391 	/* run main-loop with timeout, wait for events */
392 	err = re_main_timeout(5000);
393 	TEST_ERR(err);
394 	TEST_ERR(fix.err);
395 
396 	ASSERT_EQ(1, fix.a.n_established);
397 	ASSERT_EQ(1, fix.a.n_closed);
398 	ASSERT_EQ(0, fix.a.close_scode);
399 
400 	ASSERT_EQ(1, fix.b.n_established);
401 	ASSERT_EQ(1, fix.b.n_closed);
402 	ASSERT_EQ(0, fix.b.close_scode);
403 
404  out:
405 	fixture_close(f);
406 
407 	return err;
408 }
409 
410 
test_call_rtp_timeout(void)411 int test_call_rtp_timeout(void)
412 {
413 #define RTP_TIMEOUT_MS 1
414 	struct fixture fix, *f = &fix;
415 	struct call *call;
416 	int err = 0;
417 
418 	fixture_init(f);
419 
420 	f->behaviour = BEHAVIOUR_ANSWER;
421 	f->estab_action = ACTION_NOTHING;
422 
423 	/* Make a call from A to B */
424 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
425 	TEST_ERR(err);
426 
427 	call = ua_call(f->a.ua);
428 	ASSERT_TRUE(call != NULL);
429 
430 	call_enable_rtp_timeout(call, RTP_TIMEOUT_MS);
431 
432 	/* run main-loop with timeout, wait for events */
433 	err = re_main_timeout(5000);
434 	TEST_ERR(err);
435 	TEST_ERR(fix.err);
436 
437 	ASSERT_EQ(1, fix.a.n_established);
438 	ASSERT_EQ(1, fix.a.n_closed);
439 	ASSERT_EQ(701, fix.a.close_scode);  /* verify timeout */
440 
441 	ASSERT_EQ(1, fix.b.n_established);
442 	ASSERT_EQ(1, fix.b.n_closed);
443 	ASSERT_EQ(0, fix.b.close_scode);
444 
445  out:
446 	fixture_close(f);
447 
448 	return err;
449 }
450 
451 
452 /* veriy that line-numbers are in sequence */
linenum_are_sequential(const struct ua * ua)453 static bool linenum_are_sequential(const struct ua *ua)
454 {
455 	uint32_t linenum = 0;
456 	struct le *le;
457 
458 	for (le = list_head(ua_calls(ua)) ; le ; le = le->next) {
459 		struct call *call = le->data;
460 
461 		if (call_linenum(call) <= linenum)
462 			return false;
463 
464 		linenum = call_linenum(call);
465 	}
466 
467 	return true;
468 }
469 
470 
test_call_multiple(void)471 int test_call_multiple(void)
472 {
473 	struct fixture fix, *f = &fix;
474 	struct le *le;
475 	unsigned i;
476 	int err = 0;
477 
478 	fixture_init(f);
479 
480 	f->behaviour = BEHAVIOUR_ANSWER;
481 	f->exp_estab = 4;
482 
483 	/*
484 	 * Step 1 -- make 4 calls from A to B
485 	 */
486 	for (i=0; i<4; i++) {
487 		err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
488 		TEST_ERR(err);
489 	}
490 
491 	err = re_main_timeout(5000);
492 	TEST_ERR(err);
493 	TEST_ERR(fix.err);
494 
495 	ASSERT_EQ(0, fix.a.n_incoming);
496 	ASSERT_EQ(4, fix.a.n_established);
497 	ASSERT_EQ(0, fix.a.n_closed);
498 
499 	ASSERT_EQ(4, fix.b.n_incoming);
500 	ASSERT_EQ(4, fix.b.n_established);
501 	ASSERT_EQ(0, fix.b.n_closed);
502 
503 	ASSERT_EQ(4, list_count(ua_calls(f->a.ua)));
504 	ASSERT_EQ(4, list_count(ua_calls(f->b.ua)));
505 	ASSERT_TRUE(linenum_are_sequential(f->a.ua));
506 	ASSERT_TRUE(linenum_are_sequential(f->b.ua));
507 
508 
509 	/*
510 	 * Step 2 -- hangup calls with even line-number
511 	 */
512 
513 	f->exp_closed = 2;
514 
515 	le = list_head(ua_calls(f->a.ua));
516 	while (le) {
517 		struct call *call = le->data;
518 		le = le->next;
519 
520 		if (!(call_linenum(call) % 2)) {
521 			ua_hangup(f->a.ua, call, 0, 0);
522 		}
523 	}
524 
525 	err = re_main_timeout(5000);
526 	TEST_ERR(err);
527 	TEST_ERR(fix.err);
528 
529 	ASSERT_EQ(2, list_count(ua_calls(f->a.ua)));
530 	ASSERT_EQ(2, list_count(ua_calls(f->b.ua)));
531 	ASSERT_TRUE(linenum_are_sequential(f->a.ua));
532 	ASSERT_TRUE(linenum_are_sequential(f->b.ua));
533 
534 
535 	/*
536 	 * Step 3 -- make 2 calls from A to B
537 	 */
538 
539 	f->a.n_established = 0;
540 	f->b.n_established = 0;
541 	f->exp_estab = 2;
542 	for (i=0; i<2; i++) {
543 		err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
544 		TEST_ERR(err);
545 	}
546 
547 	err = re_main_timeout(5000);
548 	TEST_ERR(err);
549 	TEST_ERR(fix.err);
550 
551 	ASSERT_EQ(4, list_count(ua_calls(f->a.ua)));
552 	ASSERT_EQ(4, list_count(ua_calls(f->b.ua)));
553 
554  out:
555 	fixture_close(f);
556 
557 	return err;
558 }
559 
560 
test_call_max(void)561 int test_call_max(void)
562 {
563 	struct fixture fix, *f = &fix;
564 	unsigned i;
565 	int err = 0;
566 
567 	/* Set the max-calls limit */
568 	conf_config()->call.max_calls = 1;
569 
570 	fixture_init(f);
571 
572 	f->behaviour = BEHAVIOUR_ANSWER;
573 
574 	/* Make 2 calls, one should work and one should fail */
575 	for (i=0; i<2; i++) {
576 		err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
577 		TEST_ERR(err);
578 	}
579 
580 	f->b.failed = true; /* tiny hack to stop the runloop */
581 
582 	err = re_main_timeout(5000);
583 	TEST_ERR(err);
584 	TEST_ERR(fix.err);
585 
586 	ASSERT_EQ(0, fix.a.n_incoming);
587 	ASSERT_EQ(1, fix.a.n_established);
588 	ASSERT_EQ(1, fix.a.n_closed);
589 	ASSERT_EQ(486, fix.a.close_scode);
590 
591 	ASSERT_EQ(1, fix.b.n_incoming);
592 	ASSERT_EQ(0, fix.b.n_closed);
593 
594  out:
595 	fixture_close(f);
596 
597 	return err;
598 }
599 
600 
601 static const char dtmf_digits[] = "123";
602 
603 
dtmf_handler(struct call * call,char key,void * arg)604 static void dtmf_handler(struct call *call, char key, void *arg)
605 {
606 	struct agent *ag = arg;
607 	int err = 0;
608 	(void)call;
609 
610 	/* ignore key-release */
611 	if (key == KEYCODE_REL)
612 		return;
613 
614 	ASSERT_EQ(dtmf_digits[ag->n_dtmf_recv], key);
615 	++ag->n_dtmf_recv;
616 
617 	if (ag->n_dtmf_recv >= str_len(dtmf_digits)) {
618 		re_cancel();
619 	}
620 
621  out:
622 	if (err) {
623 		fixture_abort(ag->fix, err);
624 	}
625 }
626 
627 
test_call_dtmf(void)628 int test_call_dtmf(void)
629 {
630 	struct fixture fix, *f = &fix;
631 	struct ausrc *ausrc = NULL;
632 	size_t i, n = str_len(dtmf_digits);
633 	int err = 0;
634 
635 	/* Use a low packet time, so the test completes quickly */
636 	fixture_init_prm(f, ";ptime=1");
637 
638 	/* audio-source is needed for dtmf/telev to work */
639 	err = mock_ausrc_register(&ausrc);
640 	TEST_ERR(err);
641 
642 	f->behaviour = BEHAVIOUR_ANSWER;
643 
644 	/* Make a call from A to B */
645 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
646 	TEST_ERR(err);
647 
648 	/* run main-loop with timeout, wait for events */
649 	err = re_main_timeout(5000);
650 	TEST_ERR(err);
651 	TEST_ERR(fix.err);
652 
653 	call_set_handlers(ua_call(f->a.ua), NULL, dtmf_handler, &f->a);
654 	call_set_handlers(ua_call(f->b.ua), NULL, dtmf_handler, &f->b);
655 
656 	/* send some DTMF digits from A to B .. */
657 	for (i=0; i<n; i++) {
658 		err  = call_send_digit(ua_call(f->a.ua), dtmf_digits[i]);
659 		TEST_ERR(err);
660 	}
661 
662 	/* run main-loop with timeout, wait for events */
663 	err = re_main_timeout(5000);
664 	TEST_ERR(err);
665 	TEST_ERR(fix.err);
666 
667 	ASSERT_EQ(0, fix.a.n_dtmf_recv);
668 	ASSERT_EQ(n, fix.b.n_dtmf_recv);
669 
670  out:
671 	fixture_close(f);
672 	mem_deref(ausrc);
673 
674 	return err;
675 }
676 
677 
678 #ifdef USE_VIDEO
test_call_video(void)679 int test_call_video(void)
680 {
681 	struct fixture fix, *f = &fix;
682 	struct vidsrc *vidsrc = NULL;
683 	struct vidisp *vidisp = NULL;
684 	int err = 0;
685 
686 	conf_config()->video.fps = 100;
687 
688 	fixture_init(f);
689 
690 	/* to enable video, we need one vidsrc and vidcodec */
691 	mock_vidcodec_register();
692 	err = mock_vidsrc_register(&vidsrc);
693 	TEST_ERR(err);
694 	err = mock_vidisp_register(&vidisp);
695 	TEST_ERR(err);
696 
697 	f->behaviour = BEHAVIOUR_ANSWER;
698 	f->estab_action = ACTION_NOTHING;
699 
700 	/* Make a call from A to B */
701 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_ON);
702 	TEST_ERR(err);
703 
704 	/* run main-loop with timeout, wait for events */
705 	err = re_main_timeout(10000);
706 	TEST_ERR(err);
707 	TEST_ERR(fix.err);
708 
709 	/* verify that video was enabled for this call */
710 	ASSERT_EQ(1, fix.a.n_established);
711 	ASSERT_EQ(1, fix.b.n_established);
712 
713 	ASSERT_TRUE(call_has_video(ua_call(f->a.ua)));
714 	ASSERT_TRUE(call_has_video(ua_call(f->b.ua)));
715 
716  out:
717 	fixture_close(f);
718 	mem_deref(vidisp);
719 	mem_deref(vidsrc);
720 	mock_vidcodec_unregister();
721 
722 	return err;
723 }
724 #endif
725 
726 
mock_sample_handler(const void * sampv,size_t sampc,void * arg)727 static void mock_sample_handler(const void *sampv, size_t sampc, void *arg)
728 {
729 	struct fixture *fix = arg;
730 	bool got_aulevel;
731 	(void)sampv;
732 	(void)sampc;
733 
734 	got_aulevel =
735 		0 == audio_level_get(call_audio(ua_call(fix->a.ua)), NULL) &&
736 		0 == audio_level_get(call_audio(ua_call(fix->b.ua)), NULL);
737 
738 	if (got_aulevel)
739 		re_cancel();
740 }
741 
742 
test_call_aulevel(void)743 int test_call_aulevel(void)
744 {
745 	struct fixture fix, *f = &fix;
746 	struct ausrc *ausrc = NULL;
747 	struct auplay *auplay = NULL;
748 	double lvl;
749 	int err = 0;
750 
751 	/* Use a low packet time, so the test completes quickly */
752 	fixture_init_prm(f, ";ptime=1");
753 
754 	conf_config()->audio.level = true;
755 
756 	err = mock_ausrc_register(&ausrc);
757 	TEST_ERR(err);
758 	err = mock_auplay_register(&auplay, mock_sample_handler, f);
759 	TEST_ERR(err);
760 
761 	f->estab_action = ACTION_NOTHING;
762 
763 	/* Make a call from A to B */
764 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
765 	TEST_ERR(err);
766 
767 	/* run main-loop with timeout, wait for events */
768 	err = re_main_timeout(5000);
769 	TEST_ERR(err);
770 	TEST_ERR(fix.err);
771 
772 	/* verify audio silence */
773 	err = audio_level_get(call_audio(ua_call(f->a.ua)), &lvl);
774 	TEST_ERR(err);
775 	ASSERT_EQ(-96, lvl);
776 	err = audio_level_get(call_audio(ua_call(f->b.ua)), &lvl);
777 	TEST_ERR(err);
778 	ASSERT_EQ(-96, lvl);
779 
780  out:
781 	conf_config()->audio.level = false;
782 
783 	fixture_close(f);
784 	mem_deref(auplay);
785 	mem_deref(ausrc);
786 
787 	return err;
788 }
789 
790 
test_call_progress(void)791 int test_call_progress(void)
792 {
793 	struct fixture fix, *f = &fix;
794 	int err = 0;
795 
796 	fixture_init(f);
797 
798 	f->behaviour = BEHAVIOUR_PROGRESS;
799 
800 	/* Make a call from A to B */
801 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
802 	TEST_ERR(err);
803 
804 	/* run main-loop with timeout, wait for events */
805 	err = re_main_timeout(5000);
806 	TEST_ERR(err);
807 	TEST_ERR(fix.err);
808 
809 	ASSERT_EQ(0, fix.a.n_incoming);
810 	ASSERT_EQ(1, fix.a.n_progress);
811 	ASSERT_EQ(0, fix.a.n_established);
812 	ASSERT_EQ(0, fix.a.n_closed);
813 	ASSERT_EQ(0, fix.a.close_scode);
814 
815 	ASSERT_EQ(1, fix.b.n_incoming);
816 	ASSERT_EQ(0, fix.b.n_progress);
817 	ASSERT_EQ(0, fix.b.n_established);
818 	ASSERT_EQ(0, fix.b.n_closed);
819 
820  out:
821 	fixture_close(f);
822 
823 	return err;
824 }
825 
826 
float_sample_handler(const void * sampv,size_t sampc,void * arg)827 static void float_sample_handler(const void *sampv, size_t sampc, void *arg)
828 {
829 	struct fixture *fix = arg;
830 	(void)sampv;
831 	(void)sampc;
832 
833 	if (sampc && fix->a.n_established && fix->b.n_established)
834 		re_cancel();
835 }
836 
837 
test_media_base(enum audio_mode txmode)838 static int test_media_base(enum audio_mode txmode)
839 {
840 	struct fixture fix, *f = &fix;
841 	struct ausrc *ausrc = NULL;
842 	struct auplay *auplay = NULL;
843 	int err = 0;
844 
845 	fixture_init(f);
846 
847 	conf_config()->audio.txmode = txmode;
848 
849 	conf_config()->audio.src_fmt = AUFMT_FLOAT;
850 	conf_config()->audio.play_fmt = AUFMT_FLOAT;
851 
852 	err = mock_ausrc_register(&ausrc);
853 	TEST_ERR(err);
854 	err = mock_auplay_register(&auplay, float_sample_handler, f);
855 	TEST_ERR(err);
856 
857 	f->estab_action = ACTION_NOTHING;
858 
859 	f->behaviour = BEHAVIOUR_ANSWER;
860 
861 	/* Make a call from A to B */
862 	err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF);
863 	TEST_ERR(err);
864 
865 	/* run main-loop with timeout, wait for events */
866 	err = re_main_timeout(5000);
867 	TEST_ERR(err);
868 	TEST_ERR(fix.err);
869 
870 	ASSERT_EQ(0, fix.a.n_incoming);
871 	ASSERT_EQ(1, fix.a.n_established);
872 	ASSERT_EQ(0, fix.a.n_closed);
873 	ASSERT_EQ(0, fix.a.close_scode);
874 
875 	ASSERT_EQ(1, fix.b.n_incoming);
876 	ASSERT_EQ(1, fix.b.n_established);
877 	ASSERT_EQ(0, fix.b.n_closed);
878 
879  out:
880 	conf_config()->audio.src_fmt = AUFMT_S16LE;
881 	conf_config()->audio.play_fmt = AUFMT_S16LE;
882 
883 	fixture_close(f);
884 	mem_deref(auplay);
885 	mem_deref(ausrc);
886 
887 	if (fix.err)
888 		return fix.err;
889 
890 	return err;
891 }
892 
893 
test_call_format_float(void)894 int test_call_format_float(void)
895 {
896 	int err;
897 
898 	err = test_media_base(AUDIO_MODE_POLL);
899 	ASSERT_EQ(0, err);
900 
901 	err = test_media_base(AUDIO_MODE_THREAD);
902 	ASSERT_EQ(0, err);
903 
904 	conf_config()->audio.txmode = AUDIO_MODE_POLL;
905 
906  out:
907 	return err;
908 }
909