diff --git a/daemon/call.c b/daemon/call.c index 917186774..2df0fd510 100644 --- a/daemon/call.c +++ b/daemon/call.c @@ -2620,7 +2620,7 @@ static void __media_init_from_flags(struct call_media *other_media, struct call_ struct stream_params *sp, sdp_ng_flags *flags) { call_t *call = other_media->call; - str_q *additional_attributes = &sp->attributes; /* attributes in str format */ + __auto_type additional_attributes = &sp->attributes; /* attributes in str format */ if (flags->opmode == OP_OFFER && flags->reset) { if (media) @@ -2706,7 +2706,7 @@ static void __media_init_from_flags(struct call_media *other_media, struct call_ * other (unknown type) */ if (media) { - t_queue_clear_full(&media->sdp_attributes, str_free); + t_queue_clear_full(&media->sdp_attributes, sdp_attr_free); media->sdp_attributes = *additional_attributes; t_queue_init(additional_attributes); } @@ -3838,7 +3838,7 @@ void call_media_free(struct call_media **mdp) { codec_handlers_free(md); codec_handler_free(&md->t38_handler); t38_gateway_put(&md->t38_gateway); - t_queue_clear_full(&md->sdp_attributes, str_free); + t_queue_clear_full(&md->sdp_attributes, sdp_attr_free); t_queue_clear_full(&md->dtmf_recv, dtmf_event_free); t_queue_clear_full(&md->dtmf_send, dtmf_event_free); t_hash_table_destroy(md->media_subscribers_ht); @@ -3859,7 +3859,7 @@ void __monologue_free(struct call_monologue *m) { g_string_free(m->last_out_sdp, TRUE); str_free_dup(&m->last_in_sdp); sdp_sessions_clear(&m->last_in_sdp_parsed); - t_queue_clear_full(&m->sdp_attributes, str_free); + t_queue_clear_full(&m->sdp_attributes, sdp_attr_free); sdp_streams_clear(&m->last_in_sdp_streams); g_slice_free1(sizeof(*m), m); } diff --git a/daemon/sdp.c b/daemon/sdp.c index 2d43a197b..de0c89fe6 100644 --- a/daemon/sdp.c +++ b/daemon/sdp.c @@ -1678,7 +1678,7 @@ static void sp_free(struct stream_params *s) { codec_store_cleanup(&s->codecs); ice_candidates_free(&s->ice_candidates); crypto_params_sdes_queue_clear(&s->sdes_params); - t_queue_clear_full(&s->attributes, str_free); + t_queue_clear_full(&s->attributes, sdp_attr_free); g_slice_free1(sizeof(*s), s); } @@ -1763,6 +1763,20 @@ static bool legacy_osrtp_accept(struct stream_params *sp, sdp_streams_q *streams return false; } +static struct sdp_attr *sdp_attr_dup(const struct sdp_attribute *c) { + struct sdp_attr *ac = g_new0(__typeof(*ac), 1); + + str_init_dup_str(&ac->strs.name, &c->strs.name); + str_init_dup_str(&ac->strs.value, &c->strs.value); + + return ac; +} + +void sdp_attr_free(struct sdp_attr *c) { + str_free_dup(&c->strs.name); + str_free_dup(&c->strs.value); + g_free(c); +} /* XXX split this function up */ int sdp_streams(const sdp_sessions_q *sessions, sdp_streams_q *streams, sdp_ng_flags *flags) { struct sdp_session *session; @@ -1852,8 +1866,8 @@ int sdp_streams(const sdp_sessions_q *sessions, sdp_streams_q *streams, sdp_ng_f attrs = attr_list_get_by_id(&media->attributes, ATTR_EXTMAP); for (__auto_type ll = attrs ? attrs->head : NULL; ll; ll = ll->next) { attr = ll->data; - str * ret = str_dup(&attr->strs.line_value); - t_queue_push_tail(&sp->attributes, ret); + struct sdp_attr *ac = sdp_attr_dup(attr); + t_queue_push_tail(&sp->attributes, ac); } } @@ -1861,8 +1875,8 @@ int sdp_streams(const sdp_sessions_q *sessions, sdp_streams_q *streams, sdp_ng_f attrs = attr_list_get_by_id(&media->attributes, ATTR_OTHER); for (__auto_type ll = attrs ? attrs->head : NULL; ll; ll = ll->next) { attr = ll->data; - str * ret = str_dup(&attr->strs.line_value); - t_queue_push_tail(&sp->attributes, ret); + struct sdp_attr *ac = sdp_attr_dup(attr); + t_queue_push_tail(&sp->attributes, ac); } } @@ -2147,13 +2161,13 @@ static void insert_codec_parameters(GString *s, struct call_media *cm, void sdp_insert_media_attributes(GString *gs, union sdp_attr_print_arg a, const sdp_ng_flags *flags) { for (__auto_type l = a.cm->sdp_attributes.head; l; l = l->next) { __auto_type s = l->data; - append_attr_to_gstring(gs, s->s, NULL, flags, a.cm->type_id); + append_str_attr_to_gstring(gs, &s->strs.name, &s->strs.value, flags, a.cm->type_id); } } void sdp_insert_monologue_attributes(GString *gs, union sdp_attr_print_arg a, const sdp_ng_flags *flags) { for (__auto_type l = a.ml->sdp_attributes.head; l; l = l->next) { __auto_type s = l->data; - append_attr_to_gstring(gs, s->s, NULL, flags, MT_UNKNOWN); + append_str_attr_to_gstring(gs, &s->strs.name, &s->strs.value, flags, MT_UNKNOWN); } } @@ -3020,14 +3034,13 @@ struct packet_stream *print_rtcp(GString *s, struct call_media *media, packet_st /* copy sdp session attributes to the correlated monologue, as a plain text objects (str) */ void sdp_copy_session_attributes(struct call_monologue * src, struct call_monologue * dst) { - struct sdp_attribute *attr; struct sdp_session *src_session = src->last_in_sdp_parsed.head->data; attributes_q *src_attributes = attr_list_get_by_id(&src_session->attributes, ATTR_OTHER); - t_queue_clear_full(&dst->sdp_attributes, str_free); + t_queue_clear_full(&dst->sdp_attributes, sdp_attr_free); for (__auto_type ll = src_attributes ? src_attributes->head : NULL; ll; ll = ll->next) { - attr = ll->data; - str * ret = str_dup(&attr->strs.line_value); - t_queue_push_tail(&dst->sdp_attributes, ret); + struct sdp_attribute *attr = ll->data; + struct sdp_attr *ac = sdp_attr_dup(attr); + t_queue_push_tail(&dst->sdp_attributes, ac); } } static void print_sdp_session_section(GString *s, sdp_ng_flags *flags, diff --git a/daemon/t38.c b/daemon/t38.c index e2460822b..5403240c9 100644 --- a/daemon/t38.c +++ b/daemon/t38.c @@ -11,6 +11,7 @@ #include "str.h" #include "media_player.h" #include "log_funcs.h" +#include "sdp.h" diff --git a/include/call.h b/include/call.h index f5066f70b..12c0a57b9 100644 --- a/include/call.h +++ b/include/call.h @@ -331,7 +331,7 @@ struct stream_params { const struct transport_protocol *protocol; str format_str; sdes_q sdes_params; // slice-alloc'd - str_q attributes; /* just some other attributes */ + sdp_attr_q attributes; /* just some other attributes */ str direction[2]; sockfamily_t *desired_family; struct dtls_fingerprint fingerprint; @@ -469,7 +469,7 @@ struct call_media { endpoint_map_q endpoint_maps; struct codec_store codecs; - str_q sdp_attributes; /* str_sprintf() */ + sdp_attr_q sdp_attributes; /* sdp_attr_new() */ sdp_attr_print_f *sdp_attr_print; codec_handlers_ht codec_handlers; /* int payload type -> struct codec_handler XXX combine this with 'codecs' hash table? */ @@ -575,7 +575,7 @@ struct call_monologue { unsigned int dtmf_delay; /* carry `sdp_session` attributes into resulting call monologue SDP */ - str_q sdp_attributes; + sdp_attr_q sdp_attributes; sdp_attr_print_f *sdp_attr_print; atomic64 ml_flags; diff --git a/include/sdp.h b/include/sdp.h index 0703fbfba..e016d7585 100644 --- a/include/sdp.h +++ b/include/sdp.h @@ -34,6 +34,10 @@ struct sdp_attribute_strs { str key; /* "rtpmap:8" */ }; +struct sdp_attr { + struct sdp_attribute_strs strs; +}; + extern const str rtpe_instance_id; @@ -47,6 +51,8 @@ void sdp_append_str_attr(GString *s, const sdp_ng_flags *flags, enum media_type __attribute__ ((format (printf, 5, 6))); #define sdp_append_attr(s, g, t, n, f, ...) sdp_append_str_attr(s, g, t, &STR_INIT(n), f, ##__VA_ARGS__) +void sdp_attr_free(struct sdp_attr *); + int sdp_parse(str *body, sdp_sessions_q *sessions, const sdp_ng_flags *); int sdp_streams(const sdp_sessions_q *sessions, sdp_streams_q *streams, sdp_ng_flags *); void sdp_streams_clear(sdp_streams_q *); diff --git a/include/types.h b/include/types.h index 2b9f5d880..d3f46bdfa 100644 --- a/include/types.h +++ b/include/types.h @@ -52,4 +52,7 @@ TYPED_GHASHTABLE_PROTO(codec_stats_ht, char, struct codec_stats) TYPED_GQUEUE(call, call_t) +struct sdp_attr; +TYPED_GQUEUE(sdp_attr, struct sdp_attr) + #endif