From 15e1ca62af04d271504e2648656677ca86efd702 Mon Sep 17 00:00:00 2001 From: Donat Zenichev Date: Sun, 2 Mar 2025 18:16:51 +0100 Subject: [PATCH] MT#62272 moh: show real sendrecv state to originator When MoH is triggered with `sendrecv` flag (so that the recipient, the one who is put on hold, sees the sendrecv state instead of sendonly/inactive), we have to correctly process the answer coming back to the MoH originator. The originator of MoH must see: - recvonly to his sendonly - inactive to his inactive Hence OA model is kept correct for the originator's leg. Additionally: accordingly correct MoH tests. Change-Id: Ida5f074d302c419c1e57e4fd624a55bfddae5587 --- daemon/media_player.c | 9 +++++++++ daemon/sdp.c | 28 +++++++++++++++++++++++++--- include/call.h | 8 +++++++- t/auto-daemon-tests-moh.pl | 6 +++--- 4 files changed, 44 insertions(+), 7 deletions(-) diff --git a/daemon/media_player.c b/daemon/media_player.c index 42ccebf6f..259439897 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -1553,6 +1553,15 @@ check_next: /* check mode sendrecv */ if (ML_ISSET(from_ml, MOH_SENDRECV)) { bf_set(&media->media_flags, MEDIA_FLAG_SEND | MEDIA_FLAG_RECV); + bf_set(&media->media_flags, MEDIA_FLAG_FAKE_SENDRECV); + + if (media->media_subscriptions.head) { + __auto_type sub = media->media_subscriptions.head->data; + __auto_type sub_m = sub->media; + /* mark real state of originators media (no flag set - inactive, real_sendonly - sendonly) */ + if (MEDIA_ISSET(sub_m, RECV)) + bf_set(&media->media_flags, MEDIA_FLAG_REAL_SENDONLY); + } } } #endif diff --git a/daemon/sdp.c b/daemon/sdp.c index d7b23f38f..c5a0f4230 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -2692,9 +2692,31 @@ static void print_sdp_media_section(GString *s, struct call_media *media, media->sdp_attr_print(s, media, flags); /* print sendrecv */ - if (!flags->original_sendrecv) - append_attr_to_gstring(s, sdp_get_sendrecv(media), NULL, flags, - media->type_id); + if (!flags->original_sendrecv) { + /* for MoH cases, check if it's been a faked sendrecv state, + * then for an originator reveal a real sendrecv state. + */ + struct call_media *sub_m = NULL; + if (media->media_subscriptions.head) { + __auto_type sub = media->media_subscriptions.head->data; + sub_m = sub->media; + } + if (flags->opmode == OP_ANSWER && (sub_m && MEDIA_ISSET(sub_m, FAKE_SENDRECV))) + { + /* answer must be recvonly (sendonly-to-recvonly) */ + if (MEDIA_ISSET(sub_m, REAL_SENDONLY)) + append_attr_to_gstring(s, "recvonly", NULL, flags, media->type_id); + /* answer must be inactive (inactive-to-inactive) */ + else + append_attr_to_gstring(s, "inactive", NULL, flags, media->type_id); + /* clear flags for this MoH offer/answer exchange, so that future exchanges are real */ + MEDIA_CLEAR(sub_m, FAKE_SENDRECV); + MEDIA_CLEAR(sub_m, REAL_SENDONLY); + } else { + append_attr_to_gstring(s, sdp_get_sendrecv(media), NULL, flags, + media->type_id); + } + } ps_rtcp = print_rtcp(s, media, rtp_ps_link, flags); diff --git a/include/call.h b/include/call.h index c165153a3..6e627883d 100644 --- a/include/call.h +++ b/include/call.h @@ -207,11 +207,17 @@ enum { #define MEDIA_FLAG_BLACKHOLE 0x20000000 #define MEDIA_FLAG_REORDER_FORCED 0x40000000 #define MEDIA_FLAG_AUDIO_PLAYER 0x80000000 +#define MEDIA_FLAG_END_OF_CANDIDATES SHARED_FLAG_END_OF_CANDIDATES #define MEDIA_FLAG_LEGACY_OSRTP SHARED_FLAG_LEGACY_OSRTP #define MEDIA_FLAG_LEGACY_OSRTP_REV SHARED_FLAG_LEGACY_OSRTP_REV #define MEDIA_FLAG_TRANSCODING 0x100000000LL #define MEDIA_FLAG_BLOCK_EGRESS 0x200000000LL -#define MEDIA_FLAG_END_OF_CANDIDATES SHARED_FLAG_END_OF_CANDIDATES +/* MoH sendrecv flag handling, if set then hold is on-going */ +#define MEDIA_FLAG_FAKE_SENDRECV 0x400000000LL +/* in common with previous, if set, then answer has to be recvonly, + * if not set, then inactive. + */ +#define MEDIA_FLAG_REAL_SENDONLY 0x800000000LL /* struct call_monologue */ #define ML_FLAG_REC_FORWARDING 0x00010000 diff --git a/t/auto-daemon-tests-moh.pl b/t/auto-daemon-tests-moh.pl index bce5b3211..22f47543e 100644 --- a/t/auto-daemon-tests-moh.pl +++ b/t/auto-daemon-tests-moh.pl @@ -385,7 +385,7 @@ t=0 0 m=audio PORT RTP/AVP 8 c=IN IP4 203.0.113.1 a=rtpmap:8 PCMA/8000 -a=sendrecv +a=recvonly a=rtcp:PORT SDP @@ -520,7 +520,7 @@ t=0 0 m=audio PORT RTP/AVP 8 c=IN IP4 203.0.113.1 a=rtpmap:8 PCMA/8000 -a=sendrecv +a=recvonly a=rtcp:PORT SDP @@ -795,7 +795,7 @@ t=0 0 m=audio PORT RTP/AVP 8 c=IN IP4 203.0.113.1 a=rtpmap:8 PCMA/8000 -a=sendrecv +a=inactive a=rtcp:PORT SDP