MT#55283 dtmf: only update recv list if not injected and send list if injected, delayed or not blocked

having injected events on the recv list can cause out of order TS
values which results in is_in_dtmf incorrectly returning NULL and
letting the transcoded PCM frames through.
It also doesn't make sense to add DTMF to the send list unless they're
actually being sent, so injected delayed or unblocked

Change-Id: I07e2a35e27142715a5257f199326b7a3d133e2a8
(cherry picked from commit c57a3f7def)
pull/1887/head
Tom Briden 2 years ago committed by Richard Fuchs
parent 44fb8b03d5
commit bf59abf70f

@ -142,14 +142,21 @@ static void dtmf_end_event(struct call_media *media, unsigned int event, unsigne
if (!clockrate)
clockrate = 8000;
struct dtmf_event *ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = 0, .ts = ts, .volume = 0 };
g_queue_push_tail(&media->dtmf_recv, ev);
// don't add to recv list when it's injected, it can cause the list TS's to be out
// of order breaking the dtmf-security and letting the generated PCM frames through
if (!injected) {
struct dtmf_event *ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = 0, .ts = ts, .volume = 0 };
g_queue_push_tail(&media->dtmf_recv, ev);
}
ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = 0, .ts = ts + media->monologue->dtmf_delay * clockrate / 1000,
.volume = 0, .block_dtmf = media->monologue->block_dtmf };
g_queue_push_tail(&media->dtmf_send, ev);
// only add to send list if injected, a delayed send, or not being blocked
if (injected || !media->monologue->block_dtmf || media->monologue->dtmf_delay) {
struct dtmf_event *ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = 0, .ts = ts + media->monologue->dtmf_delay * clockrate / 1000,
.volume = 0, .block_dtmf = media->monologue->block_dtmf };
g_queue_push_tail(&media->dtmf_send, ev);
}
if (!dtmf_do_logging(media->call, injected))
return;
@ -288,7 +295,7 @@ static void dtmf_check_trigger(struct call_media *media, char event, uint64_t ts
}
// media->dtmf_lock must be held
static void dtmf_code_event(struct call_media *media, char event, uint64_t ts, int clockrate, int volume) {
static void dtmf_code_event(struct call_media *media, char event, uint64_t ts, int clockrate, int volume, bool injected) {
struct dtmf_event *ev = g_queue_peek_tail(&media->dtmf_recv);
if (ev && ev->code == event)
return;
@ -298,16 +305,23 @@ static void dtmf_code_event(struct call_media *media, char event, uint64_t ts, i
// check trigger before setting new dtmf_start
dtmf_check_trigger(media, event, ts, clockrate);
ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = event, .ts = ts, .volume = volume,
.rand_code = '0' + (ssl_random() % 10), .index = media->dtmf_count };
g_queue_push_tail(&media->dtmf_recv, ev);
// don't add to recv list when it's injected, it can cause the list TS's to be out
// of order breaking the dtmf-security and letting the generated PCM frames through
if (!injected) {
ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = event, .ts = ts, .volume = volume,
.rand_code = '0' + (ssl_random() % 10), .index = media->dtmf_count };
g_queue_push_tail(&media->dtmf_recv, ev);
}
ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = event, .ts = ts + media->monologue->dtmf_delay * clockrate / 1000,
.volume = volume,
.block_dtmf = media->monologue->block_dtmf };
g_queue_push_tail(&media->dtmf_send, ev);
// only add to send list if injected, a delayed send, or not being blocked
if (injected || !media->monologue->block_dtmf || media->monologue->dtmf_delay) {
ev = g_slice_alloc0(sizeof(*ev));
*ev = (struct dtmf_event) { .code = event, .ts = ts + media->monologue->dtmf_delay * clockrate / 1000,
.volume = volume,
.block_dtmf = media->monologue->block_dtmf };
g_queue_push_tail(&media->dtmf_send, ev);
}
media->dtmf_count++;
}
@ -372,7 +386,7 @@ int dtmf_event_packet(struct media_packet *mp, str *payload, int clockrate, uint
dtmf->event, dtmf->volume, dtmf->end, duration);
if (!dtmf->end) {
dtmf_code_event(mp->media, dtmf_code_to_char(dtmf->event), ts, clockrate, dtmf->volume);
dtmf_code_event(mp->media, dtmf_code_to_char(dtmf->event), ts, clockrate, dtmf->volume, false);
return 0;
}
@ -424,7 +438,7 @@ void dtmf_dsp_event(const struct dtmf_event *new_event, struct dtmf_event *cur_e
int code = dtmf_code_from_char(new_event->code); // for validation
if (code != -1)
dtmf_code_event(media, (char) new_event->code, ts, clockrate,
dtmf_volume_from_dsp(new_event->volume));
dtmf_volume_from_dsp(new_event->volume), injected);
}
}

Loading…
Cancel
Save