From 35ac2610af50038e4f3fe3dd619996ef5869c364 Mon Sep 17 00:00:00 2001 From: Tom Briden Date: Fri, 10 Mar 2023 09:54:20 +0000 Subject: [PATCH] MT#55283 Add an option to not send dtmf log events for injected dtmf global config option that defaults to false to preserve existing behaviour Closes #1627 Change-Id: I78a88fcc5c262f1786bf0812753231a0076e0c88 --- daemon/codec.c | 6 +++--- daemon/dtmf.c | 19 ++++++++++--------- daemon/main.c | 1 + daemon/media_socket.c | 2 +- daemon/rtpengine.pod | 4 ++++ etc/rtpengine.conf | 2 ++ include/codec.h | 2 +- include/dtmf.h | 4 ++-- include/main.h | 1 + 9 files changed, 25 insertions(+), 16 deletions(-) diff --git a/daemon/codec.c b/daemon/codec.c index 1b39d2fa0..67c388461 100644 --- a/daemon/codec.c +++ b/daemon/codec.c @@ -2432,15 +2432,15 @@ static void __dtmf_dsp_callback(void *ptr, int code, int level, int delay) { uint64_t ts = ch->last_dtmf_event_ts + delay; ch->last_dtmf_event_ts = ts; ts = av_rescale(ts, ch->encoder_format.clockrate, ch->dtmf_format.clockrate); - codec_add_dtmf_event(ch, code, level, ts); + codec_add_dtmf_event(ch, code, level, ts, false); } -void codec_add_dtmf_event(struct codec_ssrc_handler *ch, int code, int level, uint64_t ts) { +void codec_add_dtmf_event(struct codec_ssrc_handler *ch, int code, int level, uint64_t ts, bool injected) { struct dtmf_event new_ev = { .code = code, .volume = level, .ts = ts }; ilogs(transcoding, LOG_DEBUG, "DTMF event state change: code %i, volume %i, TS %lu", new_ev.code, new_ev.volume, (unsigned long) ts); dtmf_dsp_event(&new_ev, &ch->dtmf_state, ch->handler->media, ch->handler->source_pt.clock_rate, - ts + ch->csch.first_ts); + ts + ch->csch.first_ts, injected); // add to queue if we're doing PCM -> DTMF event conversion // this does not capture events when doing DTMF delay (dtmf_payload_type == -1) diff --git a/daemon/dtmf.c b/daemon/dtmf.c index 04288ec5c..66f85b866 100644 --- a/daemon/dtmf.c +++ b/daemon/dtmf.c @@ -15,6 +15,7 @@ static socket_t dtmf_log_sock; void dtmf_init(void) { ilog(LOG_DEBUG, "log dtmf over ng %d", rtpe_config.dtmf_via_ng); + ilog(LOG_DEBUG, "no log injected dtmf %d", rtpe_config.dtmf_no_log_injects); if (rtpe_config.dtmf_udp_ep.port) { if (connect_socket(&dtmf_log_sock, SOCK_DGRAM, &rtpe_config.dtmf_udp_ep)) ilog(LOG_ERR, "Failed to open/connect DTMF logging socket: %s", strerror(errno)); @@ -119,15 +120,15 @@ static GString *dtmf_json_print(struct call_media *media, unsigned int event, un return buf; } -bool dtmf_do_logging(void) { - if (_log_facility_dtmf || dtmf_log_sock.family || rtpe_config.dtmf_via_ng) +bool dtmf_do_logging(bool injected) { + if ((_log_facility_dtmf || dtmf_log_sock.family || rtpe_config.dtmf_via_ng) && !(injected && rtpe_config.dtmf_no_log_injects)) return true; return false; } // media->dtmf_lock must be held static void dtmf_end_event(struct call_media *media, unsigned int event, unsigned int volume, - unsigned int duration, const endpoint_t *fsin, int clockrate, bool rfc_event, uint64_t ts) + unsigned int duration, const endpoint_t *fsin, int clockrate, bool rfc_event, uint64_t ts, bool injected) { if (!clockrate) clockrate = 8000; @@ -141,7 +142,7 @@ static void dtmf_end_event(struct call_media *media, unsigned int event, unsigne .volume = 0, .block_dtmf = media->monologue->block_dtmf }; g_queue_push_tail(&media->dtmf_send, ev); - if (!dtmf_do_logging()) + if (!dtmf_do_logging(injected)) return; GString *buf = dtmf_json_print(media, event, volume, duration, fsin, clockrate); @@ -359,13 +360,13 @@ int dtmf_event_packet(struct media_packet *mp, str *payload, int clockrate, uint } dtmf_end_event(mp->media, dtmf->event, dtmf->volume, duration, - &mp->fsin, clockrate, true, ts + duration - 1); + &mp->fsin, clockrate, true, ts + duration - 1, false); return 1; } void dtmf_dsp_event(const struct dtmf_event *new_event, struct dtmf_event *cur_event_p, - struct call_media *media, int clockrate, uint64_t ts) + struct call_media *media, int clockrate, uint64_t ts, bool injected) { // update state tracker regardless of outcome struct dtmf_event cur_event = *cur_event_p; @@ -397,7 +398,7 @@ void dtmf_dsp_event(const struct dtmf_event *new_event, struct dtmf_event *cur_e cur_event.code, cur_event.volume, duration); dtmf_end_event(media, dtmf_code_from_char(cur_event.code), dtmf_volume_from_dsp(cur_event.volume), - duration, &ps->endpoint, clockrate, false, ts); + duration, &ps->endpoint, clockrate, false, ts, injected); } else { ilog(LOG_DEBUG, "DTMF DSP code event: event %u, volume %u, duration %u", @@ -632,8 +633,8 @@ const char *dtmf_inject(struct call_media *media, int code, int volume, int dura // shift this new event past the end of the last event plus a pause start_pts = last_end_pts + pause * ch->dest_pt.clock_rate / 1000; } - codec_add_dtmf_event(csh, dtmf_code_to_char(code), volume, start_pts); - codec_add_dtmf_event(csh, 0, 0, start_pts + num_samples); + codec_add_dtmf_event(csh, dtmf_code_to_char(code), volume, start_pts, true); + codec_add_dtmf_event(csh, 0, 0, start_pts + num_samples, true); obj_put_o((struct obj *) csh); return NULL; diff --git a/daemon/main.c b/daemon/main.c index 68d569750..28f4f4cab 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -500,6 +500,7 @@ static void options(int *argc, char ***argv) { { "dtmf-log-ng-tcp", 0,0, G_OPTION_ARG_NONE, &rtpe_config.dtmf_via_ng, "DTMF logging via TCP NG protocol", NULL }, { "dtmf-no-suppress", 0,0,G_OPTION_ARG_NONE, &rtpe_config.dtmf_no_suppress, "Disable audio suppression during DTMF events", NULL }, { "dtmf-digit-delay", 0,0,G_OPTION_ARG_INT, &rtpe_config.dtmf_digit_delay, "Delay in ms between DTMF digit for trigger detection", NULL }, + { "dtmf-no-log-injects", 0,0,G_OPTION_ARG_NONE, &rtpe_config.dtmf_no_log_injects, "Disable DTMF logging for events created by inject-DTMF function", NULL}, #endif { "log-format", 0, 0, G_OPTION_ARG_STRING, &log_format, "Log prefix format", "default|parsable"}, { "xmlrpc-format",'x', 0, G_OPTION_ARG_INT, &rtpe_config.fmt, "XMLRPC timeout request format to use. 0: SEMS DI, 1: call-id only, 2: Kamailio", "INT" }, diff --git a/daemon/media_socket.c b/daemon/media_socket.c index 0546f00a6..a3088a9ce 100644 --- a/daemon/media_socket.c +++ b/daemon/media_socket.c @@ -1703,7 +1703,7 @@ static const struct streamhandler *__determine_handler(struct packet_stream *in, if (!sh) must_recrypt = true; - else if (dtmf_do_logging()) + else if (dtmf_do_logging(false)) must_recrypt = true; else if (MEDIA_ISSET(in->media, DTLS) || (out && MEDIA_ISSET(out->media, DTLS))) must_recrypt = true; diff --git a/daemon/rtpengine.pod b/daemon/rtpengine.pod index cfc1f2664..5dc098fb0 100644 --- a/daemon/rtpengine.pod +++ b/daemon/rtpengine.pod @@ -298,6 +298,10 @@ given address as UDP packets. If B<--listen-tcp-ng> is enabled, this will send DTMF events to all connected clients encoded in bencode format. +=item B<--dtmf-no-log-injects> +If B<--dtmf-no-log-injects> is enabled, DTMF events resulting from a +call to inject-DTMF won't be sent to B<--dtmf-log-dest=> or B<--listen-tcp-ng> + =item B<--dtmf-no-suppress> Some RTP clients continue to send audio RTP packets during a DTMF event, diff --git a/etc/rtpengine.conf b/etc/rtpengine.conf index cfcc88d76..e40702611 100644 --- a/etc/rtpengine.conf +++ b/etc/rtpengine.conf @@ -90,6 +90,8 @@ recording-method = proc # dtls-signature = sha-256 # dtls-ciphers = DEFAULT:!NULL:!aNULL:!SHA256:!SHA384:!aECDH:!AESGCM+AES256:!aPSK +# dtmf-no-log-injects = 0 + # graphite = 127.0.0.1:9006 # graphite-interval = 60 # graphite-prefix = foobar. diff --git a/include/codec.h b/include/codec.h index 39de5b670..ab277234a 100644 --- a/include/codec.h +++ b/include/codec.h @@ -148,7 +148,7 @@ void ensure_codec_def(struct rtp_payload_type *pt, struct call_media *media); void codec_handler_free(struct codec_handler **handler); bool codec_handlers_update(struct call_media *receiver, struct call_media *sink, const struct sdp_ng_flags *, const struct stream_params *); -void codec_add_dtmf_event(struct codec_ssrc_handler *ch, int code, int level, uint64_t ts); +void codec_add_dtmf_event(struct codec_ssrc_handler *ch, int code, int level, uint64_t ts, bool injected); uint64_t codec_last_dtmf_event(struct codec_ssrc_handler *ch); uint64_t codec_encoder_pts(struct codec_ssrc_handler *ch); void codec_decoder_skip_pts(struct codec_ssrc_handler *ch, uint64_t); diff --git a/include/dtmf.h b/include/dtmf.h index 1c02d1ae8..96c72957a 100644 --- a/include/dtmf.h +++ b/include/dtmf.h @@ -33,9 +33,9 @@ int dtmf_code_from_char(char); char dtmf_code_to_char(int code); const char *dtmf_inject(struct call_media *media, int code, int volume, int duration, int pause, struct call_media *sink); -bool dtmf_do_logging(void); +bool dtmf_do_logging(bool injected); void dtmf_dsp_event(const struct dtmf_event *new_event, struct dtmf_event *cur_event, - struct call_media *media, int clockrate, uint64_t ts); + struct call_media *media, int clockrate, uint64_t ts, bool injected); enum block_dtmf_mode dtmf_get_block_mode(struct call *call, struct call_monologue *ml); bool is_pcm_dtmf_block_mode(enum block_dtmf_mode mode); bool is_dtmf_replace_mode(enum block_dtmf_mode mode); diff --git a/include/main.h b/include/main.h index 5b569854c..b38421f9e 100644 --- a/include/main.h +++ b/include/main.h @@ -108,6 +108,7 @@ struct rtpengine_config { int dtmf_via_ng; int dtmf_no_suppress; int dtmf_digit_delay; + int dtmf_no_log_injects; enum endpoint_learning endpoint_learning; int jb_length; int jb_clock_drift;