diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index f0a6d5859..54cb436ae 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -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, 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); if (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)) { /* whom to stop the moh audio */ diff --git a/daemon/media_player.c b/daemon/media_player.c index e3eb70fa1..9236f4640 100644 --- a/daemon/media_player.c +++ b/daemon/media_player.c @@ -1227,6 +1227,40 @@ bool call_ml_stops_moh(struct call_monologue *from_ml, struct call_monologue *to 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, media_player_opts_t opts, sdp_ng_flags *flags) { diff --git a/include/media_player.h b/include/media_player.h index 279a4461e..128ee37bf 100644 --- a/include/media_player.h +++ b/include/media_player.h @@ -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_stops_moh(struct call_monologue *from_ml, struct call_monologue *to_ml, enum ng_opmode opmode); +void call_ml_moh_set_zeroconn(struct call_monologue *from_ml); void media_player_init(void); void media_player_free(void); diff --git a/t/auto-daemon-tests.pl b/t/auto-daemon-tests.pl index 651b3dcca..214c18818 100755 --- a/t/auto-daemon-tests.pl +++ b/t/auto-daemon-tests.pl @@ -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)]); # declare that offerer is capable of moh -offer('Music on hold - sendrecv', { ICE => 'remove', DTLS => 'off', moh => { blob => $wav_file, connection => 'zero', mode => 'sendrecv' } }, < 'remove', DTLS => 'off', moh => { blob => $wav_file, mode => 'sendrecv' } }, < 'remove', moh => { 'db-id' => '123', connection => 'zero', mode => 'sendrecv' } }, < 'remove', moh => { 'db-id' => '123', mode => 'sendrecv' } }, < 'remove', DTLS => 'off', moh => { blob => $wav_file, connection => 'zero', mode => 'sendrecv' } }, < 'remove', moh => { 'db-id' => '123', connection => 'zero', mode => 'sendrecv' } }, < 'remove', DTLS => 'off' }, < 'remove' }, < 'remove', DTLS => 'off' }, < 'remove' }, <