diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/call.c | 99 | ||||
-rw-r--r-- | test/main.c | 1 | ||||
-rw-r--r-- | test/mock/mock_ausrc.c | 88 | ||||
-rw-r--r-- | test/srcs.mk | 2 | ||||
-rw-r--r-- | test/test.h | 9 |
5 files changed, 196 insertions, 3 deletions
diff --git a/test/call.c b/test/call.c index b752228..8495761 100644 --- a/test/call.c +++ b/test/call.c @@ -25,6 +25,7 @@ enum action { }; struct agent { + struct fixture *fix; /* pointer to parent */ struct agent *peer; struct ua *ua; uint16_t close_scode; @@ -33,6 +34,7 @@ struct agent { unsigned n_incoming; unsigned n_established; unsigned n_closed; + unsigned n_dtmf_recv; }; struct fixture { @@ -48,9 +50,12 @@ struct fixture { }; -#define fixture_init(f) \ +#define fixture_init_prm(f, prm) \ memset(f, 0, sizeof(*f)); \ \ + f->a.fix = f; \ + f->b.fix = f; \ + \ err = ua_init("test", true, true, true, false); \ TEST_ERR(err); \ \ @@ -59,9 +64,11 @@ struct fixture { f->exp_closed = 1; \ aucodec_register(&dummy_pcma); \ \ - err = ua_alloc(&f->a.ua, "A <sip:a:xxx@127.0.0.1>;regint=0"); \ + err = ua_alloc(&f->a.ua, \ + "A <sip:a:xxx@127.0.0.1>;regint=0" prm); \ TEST_ERR(err); \ - err = ua_alloc(&f->b.ua, "B <sip:b:xxx@127.0.0.1>;regint=0"); \ + err = ua_alloc(&f->b.ua, \ + "B <sip:b:xxx@127.0.0.1>;regint=0" prm); \ TEST_ERR(err); \ \ f->a.peer = &f->b; \ @@ -77,6 +84,10 @@ struct fixture { re_snprintf(f->buri, sizeof(f->buri), "sip:b@%J", &f->laddr_sip); +#define fixture_init(f) \ + fixture_init_prm((f), ""); + + #define fixture_close(f) \ mem_deref(f->b.ua); \ mem_deref(f->a.ua); \ @@ -88,6 +99,12 @@ struct fixture { ua_stop_all(true); \ ua_close(); +#define fixture_abort(f, error) \ + do { \ + (f)->err = (error); \ + re_cancel(); \ + } while (0) + static struct aucodec dummy_pcma = { .pt = "8", @@ -569,3 +586,79 @@ int test_call_max(void) return err; } + + +static const char dtmf_digits[] = "123"; + + +static void dtmf_handler(struct call *call, char key, void *arg) +{ + struct agent *ag = arg; + int err = 0; + + /* ignore key-release */ + if (key == 0) + return; + + ASSERT_EQ(dtmf_digits[ag->n_dtmf_recv], key); + ++ag->n_dtmf_recv; + + if (ag->n_dtmf_recv >= str_len(dtmf_digits)) { + re_cancel(); + } + + out: + if (err) { + fixture_abort(ag->fix, err); + } +} + + +int test_call_dtmf(void) +{ + struct fixture fix, *f = &fix; + struct ausrc *ausrc = NULL; + size_t i, n = str_len(dtmf_digits); + int err = 0; + + /* Use a low packet time, so the test completes quickly */ + fixture_init_prm(f, ";ptime=1"); + + /* audio-source is needed for dtmf/telev to work */ + err = mock_ausrc_register(&ausrc); + TEST_ERR(err); + + f->behaviour = BEHAVIOUR_ANSWER; + + /* Make a call from A to B */ + err = ua_connect(f->a.ua, 0, NULL, f->buri, NULL, VIDMODE_OFF); + TEST_ERR(err); + + /* run main-loop with timeout, wait for events */ + err = re_main_timeout(5000); + TEST_ERR(err); + TEST_ERR(fix.err); + + call_set_handlers(ua_call(f->a.ua), NULL, dtmf_handler, &f->a); + call_set_handlers(ua_call(f->b.ua), NULL, dtmf_handler, &f->b); + + /* send some DTMF digits from A to B .. */ + for (i=0; i<n; i++) { + err = call_send_digit(ua_call(f->a.ua), dtmf_digits[i]); + TEST_ERR(err); + } + + /* run main-loop with timeout, wait for events */ + err = re_main_timeout(5000); + TEST_ERR(err); + TEST_ERR(fix.err); + + ASSERT_EQ(0, fix.a.n_dtmf_recv); + ASSERT_EQ(n, fix.b.n_dtmf_recv); + + out: + fixture_close(f); + mem_deref(ausrc); + + return err; +} diff --git a/test/main.c b/test/main.c index c0bc1c1..6991671 100644 --- a/test/main.c +++ b/test/main.c @@ -27,6 +27,7 @@ static const struct test tests[] = { TEST(test_call_rtp_timeout), TEST(test_call_multiple), TEST(test_call_max), + TEST(test_call_dtmf), TEST(test_cmd), TEST(test_contact), TEST(test_cplusplus), diff --git a/test/mock/mock_ausrc.c b/test/mock/mock_ausrc.c new file mode 100644 index 0000000..8e29dbf --- /dev/null +++ b/test/mock/mock_ausrc.c @@ -0,0 +1,88 @@ +/** + * @file mock/mock_ausrc.c Mock audio source + * + * Copyright (C) 2010 - 2016 Creytiv.com + */ +#include <re.h> +#include <baresip.h> +#include "../test.h" + + +struct ausrc_st { + const struct ausrc *as; /* inheritance */ + + struct tmr tmr; + struct ausrc_prm prm; + int16_t *sampv; + size_t sampc; + ausrc_read_h *rh; + void *arg; +}; + + +static void tmr_handler(void *arg) +{ + struct ausrc_st *st = arg; + + tmr_start(&st->tmr, st->prm.ptime, tmr_handler, st); + + if (st->rh) + st->rh(st->sampv, st->sampc, st->arg); +} + + +static void ausrc_destructor(void *arg) +{ + struct ausrc_st *st = arg; + + tmr_cancel(&st->tmr); + mem_deref(st->sampv); +} + + +static int mock_ausrc_alloc(struct ausrc_st **stp, const struct ausrc *as, + struct media_ctx **ctx, + struct ausrc_prm *prm, const char *device, + ausrc_read_h *rh, ausrc_error_h *errh, void *arg) +{ + struct ausrc_st *st; + int err = 0; + (void)ctx; + (void)errh; + + if (!stp || !as || !prm) + return EINVAL; + + st = mem_zalloc(sizeof(*st), ausrc_destructor); + if (!st) + return ENOMEM; + + st->as = as; + st->prm = *prm; + st->rh = rh; + st->arg = arg; + + st->sampc = prm->srate * prm->ch * prm->ptime / 1000; + + st->sampv = mem_zalloc(2 * st->sampc, NULL); + if (!st->sampv) { + err = ENOMEM; + goto out; + } + + tmr_start(&st->tmr, 0, tmr_handler, st); + + out: + if (err) + mem_deref(st); + else + *stp = st; + + return err; +} + + +int mock_ausrc_register(struct ausrc **ausrcp) +{ + return ausrc_register(ausrcp, "mock-ausrc", mock_ausrc_alloc); +} diff --git a/test/srcs.mk b/test/srcs.mk index 2158ca8..b992822 100644 --- a/test/srcs.mk +++ b/test/srcs.mk @@ -33,6 +33,8 @@ ifneq ($(USE_TLS),) TEST_SRCS += mock/cert.c endif +TEST_SRCS += mock/mock_ausrc.c + TEST_SRCS += test.c diff --git a/test/test.h b/test/test.h index 489f8e0..4c6c11b 100644 --- a/test/test.h +++ b/test/test.h @@ -83,6 +83,14 @@ int dns_server_add_srv(struct dns_server *srv, const char *name, uint16_t pri, uint16_t weight, uint16_t port, const char *target); +/* + * Mock Audio-source + */ + +struct ausrc; + +int mock_ausrc_register(struct ausrc **ausrcp); + /* test cases */ @@ -106,6 +114,7 @@ int test_call_answer_hangup_b(void); int test_call_rtp_timeout(void); int test_call_multiple(void); int test_call_max(void); +int test_call_dtmf(void); #ifdef __cplusplus |