summaryrefslogtreecommitdiff
path: root/test/call.c
diff options
context:
space:
mode:
Diffstat (limited to 'test/call.c')
-rw-r--r--test/call.c99
1 files changed, 96 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;
+}