aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/dtmf_scheduler.h4
-rw-r--r--src/dtmf_scheduler.c19
-rw-r--r--src/mgcp_ss7.c17
-rw-r--r--tests/dtmf/dtmf_test.c33
4 files changed, 62 insertions, 11 deletions
diff --git a/include/dtmf_scheduler.h b/include/dtmf_scheduler.h
index b1a8b37..c187466 100644
--- a/include/dtmf_scheduler.h
+++ b/include/dtmf_scheduler.h
@@ -16,11 +16,15 @@ void dtmf_state_init(struct dtmf_state *state);
/* add a tone to the list */
int dtmf_state_add(struct dtmf_state *state, char tone);
+/* pop one tone from the last */
+char dtmf_state_pop_tone(struct dtmf_state *state);
+
/* tones that should be played, playing will be set to 1 */
unsigned int dtmf_state_get_pending(struct dtmf_state *state, char *tones);
/* call when the playout is done */
void dtmf_state_played(struct dtmf_state *state);
+void dtmf_state_play(struct dtmf_state *state);
unsigned int dtmf_tones_queued(struct dtmf_state *state);
diff --git a/src/dtmf_scheduler.c b/src/dtmf_scheduler.c
index 5a99a5b..dbb39e7 100644
--- a/src/dtmf_scheduler.c
+++ b/src/dtmf_scheduler.c
@@ -21,6 +21,7 @@
#include "dtmf_scheduler.h"
#include <string.h>
#include <stdio.h>
+#include <limits.h>
void dtmf_state_init(struct dtmf_state *state)
{
@@ -40,6 +41,19 @@ int dtmf_state_add(struct dtmf_state *state, char tone)
return 0;
}
+char dtmf_state_pop_tone(struct dtmf_state *state)
+{
+ char res;
+
+ if (state->size == 0)
+ return CHAR_MAX;
+
+ res = state->tones[0];
+ state->size -= 1;
+ memmove(&state->tones[0], &state->tones[1], state->size);
+ return res;
+}
+
unsigned int dtmf_state_get_pending(struct dtmf_state *state, char *tones)
{
int pos;
@@ -62,6 +76,11 @@ void dtmf_state_played(struct dtmf_state *state)
state->playing = 0;
}
+void dtmf_state_play(struct dtmf_state *state)
+{
+ state->playing = 1;
+}
+
unsigned int dtmf_tones_queued(struct dtmf_state *state)
{
return state->size;
diff --git a/src/mgcp_ss7.c b/src/mgcp_ss7.c
index 017bb8e..980f10a 100644
--- a/src/mgcp_ss7.c
+++ b/src/mgcp_ss7.c
@@ -73,20 +73,19 @@ static struct mgcp_endpoint *s_endpoints[240];
static void play_pending_tones(struct mgcp_endpoint *endp)
{
ToneGenerationT toneGeneration;
- char tones[25];
- size_t len;
+ char tones[2];
- /* Check if we need to play anything? */
- len = dtmf_state_get_pending(&endp->dtmf_state, tones);
-
- /* nothing to play? */
- if (len == 0)
+ if (dtmf_tones_queued(&endp->dtmf_state) == 0)
return;
+ /* play a single tone */
+ dtmf_state_play(&endp->dtmf_state);
+ tones[0] = dtmf_state_pop_tone(&endp->dtmf_state);
+ tones[1] = '\0';
+
/* fill out the data now */
- osmo_static_assert(sizeof(tones) <= sizeof(toneGeneration.list), Enough_space_for_tones);
memset(&toneGeneration, 0, sizeof(toneGeneration));
- toneGeneration.count = len;
+ toneGeneration.count = 1;
strcpy(toneGeneration.list, tones);
MtnSaSetMOB(endp->audio_port, ChannelType_PORT,
PredefMob_C_TONE_GENERATION, (char *) &toneGeneration,
diff --git a/tests/dtmf/dtmf_test.c b/tests/dtmf/dtmf_test.c
index 97f4f14..2759920 100644
--- a/tests/dtmf/dtmf_test.c
+++ b/tests/dtmf/dtmf_test.c
@@ -1,6 +1,6 @@
/*
- * (C) 2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2012 by On-Waves
+ * (C) 2012-2013 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2012-2013 by On-Waves
* All Rights Reserved
*
* This program is free software: you can redistribute it and/or modify
@@ -23,6 +23,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <limits.h>
#define ASSERT(got,want) \
if (got != want) { \
@@ -107,12 +108,40 @@ static void test_queue_null_byte(void)
ASSERT(dtmf_state_add(&state, 0), -2);
}
+static void test_queue_single_pop(void)
+{
+ struct dtmf_state state;
+ dtmf_state_init(&state);
+
+ /* check the empty tone */
+ ASSERT(dtmf_state_pop_tone(&state), CHAR_MAX);
+
+ dtmf_state_add(&state, '0');
+ dtmf_state_add(&state, '1');
+ dtmf_state_add(&state, '2');
+ ASSERT(dtmf_state_pop_tone(&state), '0');
+ ASSERT(dtmf_state_pop_tone(&state), '1');
+ ASSERT(dtmf_state_pop_tone(&state), '2');
+ ASSERT(dtmf_state_pop_tone(&state), CHAR_MAX);
+
+ dtmf_state_add(&state, '3');
+ dtmf_state_add(&state, '4');
+ dtmf_state_add(&state, '5');
+ ASSERT(dtmf_state_pop_tone(&state), '3');
+ ASSERT(dtmf_state_pop_tone(&state), '4');
+ dtmf_state_add(&state, '6');
+ ASSERT(dtmf_state_pop_tone(&state), '5');
+ ASSERT(dtmf_state_pop_tone(&state), '6');
+ ASSERT(dtmf_state_pop_tone(&state), CHAR_MAX);
+}
+
int main(int argc, char **argv)
{
test_queue_while_play();
test_queue_over_flow();
test_queue_null_byte();
+ test_queue_single_pop();
printf("All tests passed.\n");
return 0;
}