From 9da5a46fcb8930047aefd2a3efc967b70785efe5 Mon Sep 17 00:00:00 2001 From: Richard Fuchs Date: Wed, 6 Oct 2021 08:45:26 -0400 Subject: [PATCH] TT#136956 support DTMF-security=random Change-Id: I4100c1511be743901d302491238872990f213118 --- README.md | 4 +++- daemon/call_interfaces.c | 3 +++ daemon/codec.c | 8 +++++++ daemon/dtmf.c | 1 + include/call.h | 4 +++- lib/codeclib.c | 22 ++++++++++++++++++++ lib/codeclib.h | 2 ++ lib/dtmflib.c | 45 +++++++++++++++++++++++++--------------- lib/dtmflib.h | 9 ++++++++ 9 files changed, 79 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index e1982f6ef..2a7fe8cde 100644 --- a/README.md +++ b/README.md @@ -1524,7 +1524,9 @@ Optionally included keys are: Used in the `block DTMF` message to select the DTMF blocking mode. The default mode is `drop` which simply drops DTMF event packets. The other supported modes are: `silence` which replaces DTMF events with silence - audio; `tone` which replaces DTMF events with a single sine wave tone. + audio; `tone` which replaces DTMF events with a single sine wave tone; + `random` which replaces DTMF events with random other DTMF events (both + in-band DTMF audio tones and RFC event packets). * `delay-buffer` diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 5900cfb43..b02bfd4ab 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -1335,6 +1335,9 @@ static void call_ng_main_flags(struct sdp_ng_flags *out, str *key, bencode_item_ case CSH_LOOKUP("tone"): out->block_dtmf_mode = BLOCK_DTMF_TONE; break; + case CSH_LOOKUP("random"): + out->block_dtmf_mode = BLOCK_DTMF_RANDOM; + break; default: ilog(LOG_WARN, "Unknown 'DTMF-security' flag encountered: '" STR_FORMAT "'", STR_FMT(&s)); diff --git a/daemon/codec.c b/daemon/codec.c index 50a1e9259..17545c6be 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -2390,6 +2390,14 @@ static void delay_frame_manipulate(struct delay_frame *dframe) { frame_fill_tone_samples(frame->format, frame->extended_data[0], dframe->ts, frame->nb_samples, 400, 10, frame->sample_rate, frame->channels); break; + case BLOCK_DTMF_RANDOM: + if (!media->dtmf_event_state) + media->dtmf_event_state = '0' + (ssl_random() % 10); + frame_fill_dtmf_samples(frame->format, frame->extended_data[0], dframe->ts, + frame->nb_samples, media->dtmf_event_state - '0', + 10, frame->sample_rate, + frame->channels); + break; default: break; } diff --git a/daemon/dtmf.c b/daemon/dtmf.c index 9ac1e2015..c396dda7e 100644 --- a/daemon/dtmf.c +++ b/daemon/dtmf.c @@ -160,6 +160,7 @@ static void dtmf_code_event(struct call_media *media, char event, uint64_t ts) { media->dtmf_code = event; media->dtmf_start = ts; media->dtmf_end = 0; + media->dtmf_event_state = 0; } diff --git a/include/call.h b/include/call.h index 39eb53fd2..c0916d3be 100644 --- a/include/call.h +++ b/include/call.h @@ -206,7 +206,8 @@ enum block_dtmf_mode { BLOCK_DTMF___PCM_REPLACE_START = 2, BLOCK_DTMF_SILENCE = 2, BLOCK_DTMF_TONE = 3, - BLOCK_DTMF___PCM_REPLACE_END = 3, + BLOCK_DTMF_RANDOM = 4, + BLOCK_DTMF___PCM_REPLACE_END = 4, }; @@ -401,6 +402,7 @@ struct call_media { uint32_t dtmf_start; char dtmf_code; uint32_t dtmf_end; + unsigned int dtmf_event_state; #ifdef WITH_TRANSCODING union { struct { diff --git a/lib/codeclib.c b/lib/codeclib.c index 0ef6dc152..f856a0fe6 100644 --- a/lib/codeclib.c +++ b/lib/codeclib.c @@ -2656,3 +2656,25 @@ void frame_fill_tone_samples(enum AVSampleFormat fmt, void *samples, unsigned in break; } } + +void frame_fill_dtmf_samples(enum AVSampleFormat fmt, void *samples, unsigned int offset, unsigned int num, + unsigned int event, unsigned int volume, unsigned int sample_rate, unsigned int channels) +{ + switch (fmt) { + case AV_SAMPLE_FMT_S16: + dtmf_samples_int16_t(samples, offset, num, event, volume, sample_rate, channels); + break; + case AV_SAMPLE_FMT_S32: + dtmf_samples_int32_t(samples, offset, num, event, volume, sample_rate, channels); + break; + case AV_SAMPLE_FMT_DBL: + dtmf_samples_double(samples, offset, num, event, volume, sample_rate, channels); + break; + case AV_SAMPLE_FMT_FLT: + dtmf_samples_float(samples, offset, num, event, volume, sample_rate, channels); + break; + default: + ilog(LOG_ERR | LOG_FLAG_LIMIT, "Unsupported sample format %u", fmt); + break; + } +} diff --git a/lib/codeclib.h b/lib/codeclib.h index 9e6e9459d..b66321063 100644 --- a/lib/codeclib.h +++ b/lib/codeclib.h @@ -343,6 +343,8 @@ int packet_sequencer_insert(packet_sequencer_t *ps, seq_packet_t *); void frame_fill_tone_samples(enum AVSampleFormat fmt, void *samples, unsigned int offset, unsigned int num, unsigned int freq, unsigned int volume, unsigned int sample_rate, unsigned int channels); +void frame_fill_dtmf_samples(enum AVSampleFormat fmt, void *samples, unsigned int offset, unsigned int num, + unsigned int event, unsigned int volume, unsigned int sample_rate, unsigned int channels); #include "auxlib.h" diff --git a/lib/dtmflib.c b/lib/dtmflib.c index 02ea025e7..3392238e4 100644 --- a/lib/dtmflib.c +++ b/lib/dtmflib.c @@ -221,24 +221,35 @@ tone_samples_x(int32_t) tone_samples_x(double) tone_samples_x(float) +#define dtmf_samples_x(type) \ +void dtmf_samples_ ## type(type *samples, unsigned long offset, unsigned long num, unsigned int event, \ + unsigned int volume, unsigned int sample_rate, unsigned int channels) \ +{ \ + const struct dtmf_freq *df; \ +\ + if (event == 0xff) { \ + /* pause - silence samples */ \ + memset(samples, 0, num * sizeof(type)); \ + return; \ + } \ +\ + if (event >= G_N_ELEMENTS(dtmf_freqs)) { \ + ilog(LOG_WARN | LOG_FLAG_LIMIT, "Unsupported DTMF event %u", event); \ + memset(samples, 0, num * sizeof(type)); \ + return; \ + } \ + df = &dtmf_freqs[event]; \ +\ + freq_samples_ ## type(samples, offset, num, df->prim, df->sec, volume, sample_rate, channels); \ +} \ + +dtmf_samples_x(int16_t) +dtmf_samples_x(int32_t) +dtmf_samples_x(double) +dtmf_samples_x(float) + void dtmf_samples_int16_t_mono(void *buf, unsigned long offset, unsigned long num, unsigned int event, unsigned int volume, unsigned int sample_rate) { - int16_t *samples = buf; - const struct dtmf_freq *df; - - if (event == 0xff) { - // pause - silence samples - memset(samples, 0, num * 2); - return; - } - - if (event >= G_N_ELEMENTS(dtmf_freqs)) { - ilog(LOG_WARN | LOG_FLAG_LIMIT, "Unsupported DTMF event %u", event); - memset(buf, 0, num * 2); - return; - } - df = &dtmf_freqs[event]; - - freq_samples_int16_t(samples, offset, num, df->prim, df->sec, volume, sample_rate, 1); + dtmf_samples_int16_t(buf, offset, num, event, volume, sample_rate, 1); } diff --git a/lib/dtmflib.h b/lib/dtmflib.h index db0decb46..ba9e05019 100644 --- a/lib/dtmflib.h +++ b/lib/dtmflib.h @@ -35,5 +35,14 @@ void tone_samples_double(double *buf, unsigned long offset, unsigned long num, u void tone_samples_float(float *buf, unsigned long offset, unsigned long num, unsigned int freq, unsigned int volume, unsigned int sample_rate, unsigned int channels); +void dtmf_samples_int16_t(int16_t *buf, unsigned long offset, unsigned long num, unsigned int event, + unsigned int volume, unsigned int sample_rate, unsigned int channels); +void dtmf_samples_int32_t(int32_t *buf, unsigned long offset, unsigned long num, unsigned int event, + unsigned int volume, unsigned int sample_rate, unsigned int channels); +void dtmf_samples_double(double *buf, unsigned long offset, unsigned long num, unsigned int event, + unsigned int volume, unsigned int sample_rate, unsigned int channels); +void dtmf_samples_float(float *buf, unsigned long offset, unsigned long num, unsigned int event, + unsigned int volume, unsigned int sample_rate, unsigned int channels); + #endif