diff --git a/src/libosmocc/helper.c b/src/libosmocc/helper.c index f94d33c..6f2a718 100644 --- a/src/libosmocc/helper.c +++ b/src/libosmocc/helper.c @@ -158,10 +158,6 @@ int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **sessi abort(); } - /* once done, just ignore further messages that reply to setup */ - if (*codec_p) - return 0; - /* SDP IE */ rc = osmo_cc_get_ie_sdp(msg, 0, sdp, sizeof(sdp)); if (rc < 0) @@ -172,12 +168,22 @@ int osmo_cc_helper_audio_negotiate(osmo_cc_msg_t *msg, osmo_cc_session_t **sessi return rc; osmo_cc_session_for_each_media((*session_p)->media_list, media) { + /* skip not accepted medias */ + if (!media->accepted) + continue; /* only audio */ if (media->description.type != osmo_cc_session_media_type_audio) continue; - /* select first codec, if one was accpeted */ - if (media->codec_list) - *codec_p = media->codec_list; + osmo_cc_session_for_each_codec(media->codec_list, codec) { + /* skip not accepted codecs */ + if (!codec->accepted) + continue; + /* select first codec, if one was accpeted */ + if (!(*codec_p)) { + LOGP(DCC, LOGL_DEBUG, "Select codec '%s'.\n", codec->payload_name); + *codec_p = codec; + } + } if (*codec_p) { osmo_cc_rtp_connect(media); /* no more media streams */ diff --git a/src/libosmocc/sdp.c b/src/libosmocc/sdp.c index e350d52..f1497e9 100644 --- a/src/libosmocc/sdp.c +++ b/src/libosmocc/sdp.c @@ -36,7 +36,7 @@ } /* generate SDP from session structure */ -char *osmo_cc_session_gensdp(osmo_cc_session_t *session) +char *osmo_cc_session_gensdp(osmo_cc_session_t *session, int accepted_only) { /* calc max size of SDP: quick an dirty (close to max UDP payload size) */ static char sdp[65000]; @@ -68,6 +68,8 @@ char *osmo_cc_session_gensdp(osmo_cc_session_t *session) /* Connection Data (if all media have the same data) */ if (session->media_list) { osmo_cc_session_for_each_media(session->media_list->next, media) { + if (accepted_only && !media->accepted) + continue; if (session->media_list->connection_data_local.nettype != media->connection_data_local.nettype) break; if (session->media_list->connection_data_local.addrtype != media->connection_data_local.addrtype) @@ -87,6 +89,8 @@ char *osmo_cc_session_gensdp(osmo_cc_session_t *session) /* sendonly /recvonly (if all media have the same data) */ if (session->media_list) { osmo_cc_session_for_each_media(session->media_list->next, media) { + if (accepted_only && !media->accepted) + continue; if (session->media_list->send != media->send) break; if (session->media_list->receive != media->receive) @@ -106,12 +110,17 @@ char *osmo_cc_session_gensdp(osmo_cc_session_t *session) /* media */ osmo_cc_session_for_each_media(session->media_list, media) { + if (accepted_only && !media->accepted) + continue; strncat_printf(sdp, "m=%s %u %s", osmo_cc_session_media_type2string(media->description.type) ? : media->description.type_name, media->description.port_local, osmo_cc_session_media_proto2string(media->description.proto) ? : media->description.proto_name); - osmo_cc_session_for_each_codec(media->codec_list, codec) + osmo_cc_session_for_each_codec(media->codec_list, codec) { + if (accepted_only && !codec->accepted) + continue; strncat_printf(sdp, " %u", codec->payload_type_local); + } strncat_printf(sdp, "\r\n"); /* don't list rtpmap when session was canceled by setting port to 0 */ if (media->description.port_local == 0) @@ -119,6 +128,8 @@ char *osmo_cc_session_gensdp(osmo_cc_session_t *session) if (individual_connection_data) strncat_printf(sdp, "c=%s %s %s\r\n", osmo_cc_session_nettype2string(media->connection_data_local.nettype), osmo_cc_session_addrtype2string(media->connection_data_local.addrtype), media->connection_data_local.address); osmo_cc_session_for_each_codec(media->codec_list, codec) { + if (accepted_only && !codec->accepted) + continue; strncat_printf(sdp, "a=rtpmap:%u %s/%d", codec->payload_type_local, codec->payload_name, codec->payload_rate); if (codec->payload_channels >= 2) strncat_printf(sdp, "/%d", codec->payload_channels); diff --git a/src/libosmocc/sdp.h b/src/libosmocc/sdp.h index c9bc721..540af08 100644 --- a/src/libosmocc/sdp.h +++ b/src/libosmocc/sdp.h @@ -1,5 +1,5 @@ -char *osmo_cc_session_gensdp(struct osmo_cc_session *session); +char *osmo_cc_session_gensdp(struct osmo_cc_session *session, int accepted_only); struct osmo_cc_session *osmo_cc_session_parsesdp(osmo_cc_session_config_t *conf, void *priv, const char *_sdp); int osmo_cc_payload_type_by_attrs(uint8_t *fmt, const char *name, uint32_t *rate, int *channels); void osmo_cc_debug_sdp(const char *sdp); diff --git a/src/libosmocc/session.c b/src/libosmocc/session.c index f4e7b88..911fbb2 100644 --- a/src/libosmocc/session.c +++ b/src/libosmocc/session.c @@ -348,7 +348,7 @@ const char *osmo_cc_session_send_offer(osmo_cc_session_t *session) abort(); } - sdp = osmo_cc_session_gensdp(session); + sdp = osmo_cc_session_gensdp(session, 0); osmo_cc_debug_sdp(sdp); return sdp; @@ -419,42 +419,20 @@ void osmo_cc_session_accept_codec(osmo_cc_session_codec_t *codec, void (*encoder LOGP(DCC, LOGL_DEBUG, " -> payload channels = %d\n", codec->payload_channels); } -/* remove codecs/media that have not been accepted and generate SDP */ const char *osmo_cc_session_send_answer(osmo_cc_session_t *session) { - osmo_cc_session_media_t *media; - osmo_cc_session_codec_t *codec, **codec_p; const char *sdp; int rc; LOGP(DCC, LOGL_DEBUG, "Generating session answer.\n"); - /* loop all media */ - osmo_cc_session_for_each_media(session->media_list, media) { - /* remove unaccepted codecs */ - codec_p = &media->codec_list; - codec = *codec_p; - while (codec) { - if (!codec->accepted) { - osmo_cc_free_codec(codec); - codec = *codec_p; - continue; - } - codec_p = &codec->next; - codec = *codec_p; - } - /* mark media as unused, if no codec or not accepted */ - if (!media->accepted || !media->codec_list) - media->description.port_local = 0; - } - rc = osmo_cc_session_check(session, 0); if (rc < 0) { LOGP(DCC, LOGL_ERROR, "Please fix!\n"); abort(); } - sdp = osmo_cc_session_gensdp(session); + sdp = osmo_cc_session_gensdp(session, 1); osmo_cc_debug_sdp(sdp); return sdp; @@ -505,13 +483,14 @@ static int osmo_cc_session_negotiate(osmo_cc_session_t *session_local, struct os && codec_local->payload_channels == codec_remote->payload_channels) break; } - if (!codec_remote) { - osmo_cc_free_codec(codec_local); - codec_local = *codec_local_p; - continue; + if (codec_remote) { + /* mark as accepted, copy remote codec information */ + codec_local->accepted = 1; + codec_local->payload_type_remote = codec_remote->payload_type_remote; + } else { + /* mark as not accepted, in case it was accepted in earlier response */ + codec_local->accepted = 0; } - /* copy remote codec information */ - codec_local->payload_type_remote = codec_remote->payload_type_remote; codec_local_p = &codec_local->next; codec_local = *codec_local_p; } @@ -525,14 +504,16 @@ static int osmo_cc_session_negotiate(osmo_cc_session_t *session_local, struct os return -EINVAL; } - /* remove media with port == 0 or no codec at all */ + /* mark media as accepted, if there is a remote port and there is at least one codec */ media_local_p = &session_local->media_list; media_local = *media_local_p; while (media_local) { - if (media_local->description.port_remote == 0 || !media_local->codec_list) { - osmo_cc_free_media(media_local); - media_local = *media_local_p; - continue; + if (media_local->description.port_remote && media_local->codec_list) { + /* mark as accepted */ + media_local->accepted = 1; + } else { + /* mark as not accepted, in case it was accepted in earlier response */ + media_local->accepted = 0; } media_local_p = &media_local->next; media_local = *media_local_p;