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