diff --git a/daemon/call_interfaces.c b/daemon/call_interfaces.c index 44bf7518f..4ddea33b9 100644 --- a/daemon/call_interfaces.c +++ b/daemon/call_interfaces.c @@ -3032,6 +3032,7 @@ const char *call_subscribe_request_ng(bencode_item_t *input, bencode_item_t *out bencode_dictionary_add_integer(med_ent, "index", media->index); bencode_dictionary_add_str(med_ent, "type", &media->type); bencode_dictionary_add_str(med_ent, "label", &media->label); + bencode_dictionary_add_string(med_ent, "mode", sdp_get_sendrecv(media)); if (media_labels) { bencode_item_t *label = @@ -3041,6 +3042,7 @@ const char *call_subscribe_request_ng(bencode_item_t *input, bencode_item_t *out bencode_dictionary_add_str(label, "type", &media->type); if (source_ml->label.len) bencode_dictionary_add_str(label, "label", &source_ml->label); + bencode_dictionary_add_string(label, "mode", sdp_get_sendrecv(media)); } } } diff --git a/daemon/sdp.c b/daemon/sdp.c index b3a7fd1bb..76fe18a37 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -2514,16 +2514,21 @@ dup: monologue->last_out_sdp = g_string_new_len(chop->output->str, chop->output->len); } - -void print_sendrecv(GString *s, struct call_media *media) { +const char *sdp_get_sendrecv(struct call_media *media) { if (MEDIA_ARESET2(media, SEND, RECV)) - g_string_append(s, "a=sendrecv\r\n"); + return "sendrecv"; else if (MEDIA_ISSET(media, SEND)) - g_string_append(s, "a=sendonly\r\n"); + return "sendonly"; else if (MEDIA_ISSET(media, RECV)) - g_string_append(s, "a=recvonly\r\n"); + return "recvonly"; else - g_string_append(s, "a=inactive\r\n"); + return "inactive"; +} + +void print_sendrecv(GString *s, struct call_media *media) { + g_string_append(s, "a="); + g_string_append(s, sdp_get_sendrecv(media)); + g_string_append(s, "\r\n"); } diff --git a/include/sdp.h b/include/sdp.h index 520cf1b8c..d45ad9cb0 100644 --- a/include/sdp.h +++ b/include/sdp.h @@ -27,6 +27,7 @@ void sdp_free(GQueue *sessions); int sdp_replace(struct sdp_chopper *, GQueue *, struct call_monologue *, struct sdp_ng_flags *); int sdp_is_duplicate(GQueue *sessions); int sdp_create(str *out, struct call_monologue *, struct sdp_ng_flags *flags); +const char *sdp_get_sendrecv(struct call_media *media); int sdp_parse_candidate(struct ice_candidate *cand, const str *s); // returns -1, 0, 1 diff --git a/t/auto-daemon-tests-pubsub.pl b/t/auto-daemon-tests-pubsub.pl index cce2ec46c..ef4ec168e 100755 --- a/t/auto-daemon-tests-pubsub.pl +++ b/t/auto-daemon-tests-pubsub.pl @@ -102,6 +102,7 @@ is_deeply $tag_medias, [ index => 1, type => 'audio', label => '1', + mode => 'sendrecv', }, ], }, @@ -112,6 +113,7 @@ is_deeply $tag_medias, [ index => 1, type => 'audio', label => '0', + mode => 'sendrecv', }, ], }, @@ -121,11 +123,13 @@ is_deeply $media_labels, { index => 1, type => 'audio', tag => ft(), + mode => 'sendrecv', }, '0' => { index => 1, type => 'audio', tag => tt(), + mode => 'sendrecv', }, }, 'media-labels match'; @@ -207,6 +211,7 @@ is_deeply $tag_medias, [ index => 1, type => 'audio', label => '1', + mode => 'sendrecv', }, ], }, @@ -218,6 +223,7 @@ is_deeply $tag_medias, [ index => 1, type => 'audio', label => '0', + mode => 'sendrecv', }, ], }, @@ -228,12 +234,14 @@ is_deeply $media_labels, { type => 'audio', tag => ft(), label => 'caller', + mode => 'sendrecv', }, '0' => { index => 1, type => 'audio', tag => tt(), label => 'called', + mode => 'sendrecv', }, }, 'media-labels match'; @@ -881,6 +889,476 @@ rcv($sock_c, $port_c, rtpm(0, 4001, 7640, $ssrc_b, "\x00" x 160)); +($sock_a, $sock_b, $sock_c, $sock_d) = + new_call([qw(198.51.100.14 6118)], [qw(198.51.100.14 6120)], [qw(198.51.100.14 6122)], + [qw(198.51.100.14 6124)]); + +($port_a) = offer('SIPREC sub pause/resume', + { }, < ['all', 'SIPREC'] }, < $ttr }, < tt(), 'to-tag' => ft() }, < tt(), 'to-tag' => ft() }, < ['all', 'SIPREC'], 'to-tag' => $ttr }, < ft(), + medias => [ + { + index => 1, + type => 'audio', + label => '1', + mode => 'sendonly', + }, + ], + }, + { + tag => tt(), + medias => [ + { + index => 1, + type => 'audio', + label => '0', + mode => 'recvonly', + }, + ], + }, +], 'SIPREC sub pause/resume - tag-medias match'; +is_deeply $media_labels, { + '1' => { + index => 1, + type => 'audio', + tag => ft(), + mode => 'sendonly', + }, + '0' => { + index => 1, + type => 'audio', + tag => tt(), + mode => 'recvonly', + }, +}, 'SIPREC sub pause/resume - media-labels match'; + +subscribe_answer('SIPREC sub pause/resume', + { 'to-tag' => $ttr }, < tt(), 'to-tag' => ft() }, < tt(), 'to-tag' => ft() }, < ['all', 'SIPREC'], 'to-tag' => $ttr }, < ft(), + medias => [ + { + index => 1, + type => 'audio', + label => '1', + mode => 'sendrecv', + }, + ], + }, + { + tag => tt(), + medias => [ + { + index => 1, + type => 'audio', + label => '0', + mode => 'sendrecv', + }, + ], + }, +], 'SIPREC sub pause/resume - tag-medias match'; +is_deeply $media_labels, { + '1' => { + index => 1, + type => 'audio', + tag => ft(), + mode => 'sendrecv', + }, + '0' => { + index => 1, + type => 'audio', + tag => tt(), + mode => 'sendrecv', + }, +}, 'SIPREC sub pause/resume - media-labels match'; + +subscribe_answer('SIPREC sub pause/resume', + { 'to-tag' => $ttr }, < ft(), 'to-tag' => tt() }, < ft(), 'to-tag' => tt() }, < ['all', 'SIPREC'], 'to-tag' => $ttr }, < ft(), + medias => [ + { + index => 1, + type => 'audio', + label => '1', + mode => 'recvonly', + }, + ], + }, + { + tag => tt(), + medias => [ + { + index => 1, + type => 'audio', + label => '0', + mode => 'sendonly', + }, + ], + }, +], 'tag-medias match'; +is_deeply $media_labels, { + '1' => { + index => 1, + type => 'audio', + tag => ft(), + mode => 'recvonly', + }, + '0' => { + index => 1, + type => 'audio', + tag => tt(), + mode => 'sendonly', + }, +}, 'media-labels match'; + +subscribe_answer('SIPREC sub pause/resume', + { 'to-tag' => $ttr }, <