Browse Source

MT#61630 moh: add support of zero-connection flag

Zero-connection flag controls whether the connection
address offered in the SDP body going towards recipient
(the one who will receive the MoH media), is set
to all zeroes.

Is declared as: moh=[connection=zero]

Can be useful for older client implementations,
who want to see zeroed media when receiving sendonly
and getting put on hold.

Must be advertised once during the session origination,
and then will affect the SDP body as soon as SDP sendonly
body is received (from the behalf of one, who advertised MoH
capabilities).

SDP body recovers to the real IP addresses being inserted
into recipient's SDP, as soon as the media gets unheld.

Backwards compatibility: doesn't affect non-MoH calls.
And doesn't affect offer/answer exchanges within MoH calls,
which do not put the remote side on hold.

Additionally: previously existing MoH test adopted.

Additionally: new test introduced to check the SDP content,
when using zero-connection flag.

Change-Id: If0c38a3d294e6d5fe3886bee19ff2382e5705f9a
pull/1897/head
Donat Zenichev 12 months ago
parent
commit
3cc3b6d56c
4 changed files with 183 additions and 3 deletions
  1. +9
    -1
      daemon/call_interfaces.c
  2. +34
    -0
      daemon/media_player.c
  3. +1
    -0
      include/media_player.h
  4. +139
    -2
      t/auto-daemon-tests.pl

+ 9
- 1
daemon/call_interfaces.c View File

@ -168,6 +168,9 @@ static void updated_created_from(call_t *c, const char *addr, const endpoint_t *
} }
} }
/**
* TODO: probably makes sense to move to the call.c
*/
static const char* call_check_moh(struct call_monologue *from_ml, struct call_monologue *to_ml, static const char* call_check_moh(struct call_monologue *from_ml, struct call_monologue *to_ml,
sdp_ng_flags *flags) sdp_ng_flags *flags)
{ {
@ -189,7 +192,12 @@ static const char* call_check_moh(struct call_monologue *from_ml, struct call_mo
errstr = call_play_media_for_ml(to_ml, opts, NULL); errstr = call_play_media_for_ml(to_ml, opts, NULL);
if (errstr) if (errstr)
return errstr; return errstr;
to_ml->player->moh = true; /* mark player as used for MoH */
/* mark player as used for MoH */
to_ml->player->moh = true;
/* check if originator wants to advertise zero address during moh */
if (ML_ISSET(from_ml, MOH_ZEROCONN)) {
call_ml_moh_set_zeroconn(from_ml);
}
} else if (call_ml_stops_moh(from_ml, to_ml, flags->opmode)) } else if (call_ml_stops_moh(from_ml, to_ml, flags->opmode))
{ {
/* whom to stop the moh audio */ /* whom to stop the moh audio */


+ 34
- 0
daemon/media_player.c View File

@ -1227,6 +1227,40 @@ bool call_ml_stops_moh(struct call_monologue *from_ml, struct call_monologue *to
return false; return false;
} }
/**
* Sets zero-connection for the first found subscription media with sendonly state
* and audio type.
*/
void call_ml_moh_set_zeroconn(struct call_monologue *from_ml) {
for (int i = 0; i < from_ml->medias->len; i++)
{
struct call_media * media = from_ml->medias->pdata[i];
if (!media || media->type_id != MT_AUDIO)
continue;
if (!MEDIA_ISSET(media, SEND) && MEDIA_ISSET(media, RECV))
{
if (media->media_subscriptions.head) {
struct media_subscription * ms = media->media_subscriptions.head->data;
if (ms->media) {
struct packet_stream *ps;
__auto_type msl = ms->media->streams.head;
while (msl)
{
ps = msl->data;
if (PS_ISSET(ps, RTP)) {
ilog(LOG_DEBUG, "Forced packet stream of '"STR_FORMAT"' (media index: '%d') to zero_addr due to MoH zero-connection.",
STR_FMT(&ms->media->monologue->tag), ms->media->index);
PS_SET(ps, ZERO_ADDR);
return; /* stop */
}
msl = msl->next;
}
}
}
}
}
}
const char * call_play_media_for_ml(struct call_monologue *ml, const char * call_play_media_for_ml(struct call_monologue *ml,
media_player_opts_t opts, sdp_ng_flags *flags) media_player_opts_t opts, sdp_ng_flags *flags)
{ {


+ 1
- 0
include/media_player.h View File

@ -141,6 +141,7 @@ long long call_stop_media_for_ml(struct call_monologue *ml);
bool call_ml_wants_moh(struct call_monologue *ml, enum ng_opmode opmode); bool call_ml_wants_moh(struct call_monologue *ml, enum ng_opmode opmode);
bool call_ml_stops_moh(struct call_monologue *from_ml, struct call_monologue *to_ml, bool call_ml_stops_moh(struct call_monologue *from_ml, struct call_monologue *to_ml,
enum ng_opmode opmode); enum ng_opmode opmode);
void call_ml_moh_set_zeroconn(struct call_monologue *from_ml);
void media_player_init(void); void media_player_init(void);
void media_player_free(void); void media_player_free(void);


+ 139
- 2
t/auto-daemon-tests.pl View File

@ -26226,7 +26226,7 @@ $resp = rtpe_req('statistics', 'statistics');
($sock_a, $sock_b) = new_call([qw(198.51.100.1 33041)], [qw(198.51.100.3 33042)]); ($sock_a, $sock_b) = new_call([qw(198.51.100.1 33041)], [qw(198.51.100.3 33042)]);
# declare that offerer is capable of moh # declare that offerer is capable of moh
offer('Music on hold - sendrecv', { ICE => 'remove', DTLS => 'off', moh => { blob => $wav_file, connection => 'zero', mode => 'sendrecv' } }, <<SDP);
offer('Music on hold - sendrecv', { ICE => 'remove', DTLS => 'off', moh => { blob => $wav_file, mode => 'sendrecv' } }, <<SDP);
v=0 v=0
o=- 1545997027 1 IN IP4 198.51.100.1 o=- 1545997027 1 IN IP4 198.51.100.1
s=tester s=tester
@ -26247,7 +26247,7 @@ a=rtcp:PORT
SDP SDP
# declare that answerer is capable of moh (fake db-id) # declare that answerer is capable of moh (fake db-id)
answer('Music on hold - sendrecv', { ICE => 'remove', moh => { 'db-id' => '123', connection => 'zero', mode => 'sendrecv' } }, <<SDP);
answer('Music on hold - sendrecv', { ICE => 'remove', moh => { 'db-id' => '123', mode => 'sendrecv' } }, <<SDP);
v=0 v=0
o=- 1545997027 1 IN IP4 198.51.100.3 o=- 1545997027 1 IN IP4 198.51.100.3
s=tester s=tester
@ -26358,6 +26358,143 @@ a=sendrecv
a=rtcp:PORT a=rtcp:PORT
SDP SDP
# test MoH zero-connection
($sock_a, $sock_b) = new_call([qw(198.51.100.1 33041)], [qw(198.51.100.3 33042)]);
# declare that offerer is capable of moh
offer('Music on hold - sendrecv and declared zero-connection', { ICE => 'remove', DTLS => 'off', moh => { blob => $wav_file, connection => 'zero', mode => 'sendrecv' } }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 33041 RTP/AVP 8
c=IN IP4 198.51.100.1
a=sendrecv
----------------------------------
v=0
o=- 1545997027 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
SDP
# declare that answerer is capable of moh (fake db-id)
answer('Music on hold - sendrecv and declared zero-connection', { ICE => 'remove', moh => { 'db-id' => '123', connection => 'zero', mode => 'sendrecv' } }, <<SDP);
v=0
o=- 1545997027 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio 33042 RTP/AVP 8
c=IN IP4 198.51.100.3
a=sendrecv
--------------------------------------
v=0
o=- 1545997027 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
SDP
# offerer puts on hold
offer('Music on hold - MoH set by offerer and declared zero-connection', { ICE => 'remove', DTLS => 'off' }, <<SDP);
v=0
o=- 1545997028 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 33041 RTP/AVP 8
c=IN IP4 198.51.100.1
a=sendonly
----------------------------------
v=0
o=- 1545997028 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 0.0.0.0
a=rtpmap:8 PCMA/8000
a=sendonly
a=rtcp:PORT
SDP
# test received packets on the recepient side
(undef, $seq, $ts, $ssrc) = rcv($sock_b, -1, rtpm(8 | 0x80, -1, -1, -1, $pcma_1));
rcv($sock_b, -1, rtpm(8, $seq + 1, $ts + 160 * 1, $ssrc, $pcma_2));
rcv($sock_b, -1, rtpm(8, $seq + 2, $ts + 160 * 2, $ssrc, $pcma_3));
rcv($sock_b, -1, rtpm(8, $seq + 3, $ts + 160 * 3, $ssrc, $pcma_4));
rcv($sock_b, -1, rtpm(8, $seq + 4, $ts + 160 * 4, $ssrc, $pcma_5));
answer('Music on hold - MoH set by offerer and declared zero-connection', { ICE => 'remove' }, <<SDP);
v=0
o=- 1545997028 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio 33042 RTP/AVP 8
c=IN IP4 198.51.100.3
a=recvonly
--------------------------------------
v=0
o=- 1545997028 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=recvonly
a=rtcp:PORT
SDP
# offerer puts off hold
offer('Music on hold - MoH put off by offerer and declared zero-connection', { ICE => 'remove', DTLS => 'off' }, <<SDP);
v=0
o=- 1545997029 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio 33041 RTP/AVP 8
c=IN IP4 198.51.100.1
a=sendrecv
----------------------------------
v=0
o=- 1545997029 1 IN IP4 198.51.100.1
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
SDP
#rcv_no($sock_b);
answer('Music on hold - MoH put off by offerer and declared zero-connection', { ICE => 'remove' }, <<SDP);
v=0
o=- 1545997029 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio 33042 RTP/AVP 8
c=IN IP4 198.51.100.3
a=sendrecv
--------------------------------------
v=0
o=- 1545997029 1 IN IP4 198.51.100.3
s=tester
t=0 0
m=audio PORT RTP/AVP 8
c=IN IP4 203.0.113.1
a=rtpmap:8 PCMA/8000
a=sendrecv
a=rtcp:PORT
SDP
# SDP version tests # SDP version tests
new_call; new_call;


Loading…
Cancel
Save