From 9a3c54a523351a0fa0c1d6157da8d1e53b9cc911 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Tue, 25 Mar 2025 11:41:45 +0100 Subject: [PATCH] MT#62272 Introduce `moh-prevent-double-hold` config option Protects against double MoH played, e.g. when inadvertently two rtpengine instances try to trigger MoH. This gives a clue to the current rtpengine instance, that another one already started MoH for this call. By default is set to false. Change-Id: I7cc36a177b0ce1bdb64ff8b42bf31f13fb1e4c91 --- daemon/main.c | 1 + daemon/media_player.c | 2 +- daemon/sdp.c | 11 +++++++++++ etc/rtpengine.conf | 4 ++++ include/call_interfaces.h | 4 +++- include/main.h | 1 + 6 files changed, 21 insertions(+), 2 deletions(-) diff --git a/daemon/main.c b/daemon/main.c index 53164baed..4af97b845 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -842,6 +842,7 @@ static void options(int *argc, char ***argv, charp_ht templates) { { "moh-max-duration", 0,0, G_OPTION_ARG_INT, &rtpe_config.moh_max_duration, "Max possible duration (in milliseconds) that can be spent on playing a file. If set to 0 then will be ignored.", "INT"}, { "moh-max-repeats", 0,0, G_OPTION_ARG_INT, &rtpe_config.moh_max_repeats, "Max possible amount of playback repeats for the music on hold. player-max-duration always takes a precedence over it.", "INT"}, { "moh-attr-name", 0,0, G_OPTION_ARG_STRING, &rtpe_config.moh_attr_name, "Controls the value to be added to the session level of SDP whenever MoH is triggered.", "STRING"}, + { "moh-prevent-double-hold", 'F',0, G_OPTION_ARG_NONE, &rtpe_config.moh_prevent_double_hold, "Protects against double MoH played.", NULL}, { "max-recv-iters", 0, 0, G_OPTION_ARG_INT, &rtpe_config.max_recv_iters, "Maximum continuous reading cycles in UDP poller loop.", "INT"}, { "vsc-start-rec",0,0, G_OPTION_ARG_STRING, &rtpe_config.vsc_start_rec.s,"DTMF VSC to start recording.", "STRING"}, { "vsc-stop-rec",0,0, G_OPTION_ARG_STRING, &rtpe_config.vsc_stop_rec.s,"DTMF VSC to stop recording.", "STRING"}, diff --git a/daemon/media_player.c b/daemon/media_player.c index 5d6b7992d..e4987245a 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -1568,7 +1568,7 @@ const char * call_check_moh(struct call_monologue *from_ml, struct call_monologu sdp_ng_flags *flags) { #ifdef WITH_TRANSCODING - if (call_ml_wants_moh(from_ml, flags->opmode)) + if (!flags->moh_double_hold && call_ml_wants_moh(from_ml, flags->opmode)) { const char *errstr = NULL; diff --git a/daemon/sdp.c b/daemon/sdp.c index 9f22cf9f2..ab5ad57ef 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -65,6 +65,7 @@ enum attr_id { ATTR_MAXPTIME, ATTR_TLS_ID, ATTR_END_OF_CANDIDATES, + ATTR_MOH_ATTR_NAME, }; // make sure g_int_hash can be used static_assert(sizeof(gint) == sizeof(enum attr_id), "sizeof enum attr_id wrong"); @@ -1215,6 +1216,10 @@ static int parse_attribute(struct sdp_attribute *a) { case CSH_LOOKUP("maxptime"): a->attr = ATTR_MAXPTIME; break; + default: + /* check moh-attr-name (can be a variable attribute value) */ + if (rtpe_config.moh_attr_name && !str_cmp(&a->strs.name, rtpe_config.moh_attr_name)) + a->attr = ATTR_MOH_ATTR_NAME; } return ret; @@ -1852,6 +1857,12 @@ int sdp_streams(const sdp_sessions_q *sessions, sdp_streams_q *streams, sdp_ng_f if (attr) flags->session_group = attr->strs.value; + if (rtpe_config.moh_prevent_double_hold) { + attr = attr_get_by_id(&session->attributes, ATTR_MOH_ATTR_NAME); + if (attr) + flags->moh_double_hold = 1; + } + for (__auto_type k = session->media_streams.head; k; k = k->next) { media = k->data; diff --git a/etc/rtpengine.conf b/etc/rtpengine.conf index 914bc264e..5b4ecf53e 100644 --- a/etc/rtpengine.conf +++ b/etc/rtpengine.conf @@ -167,6 +167,10 @@ recording-method = proc # whenever MoH is triggered. If not defined, then not in use. # moh-attr-name = rtpengine-hold +# protects against double MoH played +# (e.g. when inadvertently two rtpengine instances try to trigger MoH) +# moh-prevent-double-hold = false + # preload-media-files = /var/media/file1.wav ; /var/media/file2.wav ; /var/media/file3.wav ; on-demand # media-files-reload = 60 # preload-db-media = 1; 2; 3; 4; on-demand diff --git a/include/call_interfaces.h b/include/call_interfaces.h index d8a4d480b..b95f01976 100644 --- a/include/call_interfaces.h +++ b/include/call_interfaces.h @@ -290,7 +290,9 @@ RTPE_NG_FLAGS_STR_CASE_HT_PARAMS to_tag_flag:1, moh_zero_connection:1, /* by default sendonly */ - moh_sendrecv:1; + moh_sendrecv:1, + /* prevents double MoH holds */ + moh_double_hold:1; }; diff --git a/include/main.h b/include/main.h index 41ace5e6c..1550ef174 100644 --- a/include/main.h +++ b/include/main.h @@ -128,6 +128,7 @@ enum endpoint_learning { X(measure_rtp) \ X(amr_cn_dtx) \ X(evs_cn_dtx) \ + X(moh_prevent_double_hold) \ #define RTPE_CONFIG_CHARP_PARAMS \ X(b2b_url) \