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
coverity_scan
Donat Zenichev 2 months ago
parent be49215ea8
commit 15e1ca62af

@ -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

@ -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);

@ -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

@ -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

Loading…
Cancel
Save