From 6f95bbc5d246851be1b0049d0520efe6124c439e Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 10 Jun 2014 13:25:39 +0200 Subject: [PATCH] Fix bug 0001279: Wrong usage of n_active_streams in the media descriptions. Inactive streams are now allowed between active streams in the SDP. --- coreapi/bellesip_sal/sal_op_call.c | 4 +- coreapi/bellesip_sal/sal_sdp.c | 16 +++----- coreapi/callbacks.c | 11 ++++-- coreapi/linphonecall.c | 48 +++++++++++++---------- coreapi/linphonecore.c | 6 +-- coreapi/misc.c | 52 ++++++------------------- coreapi/offeranswer.c | 20 +++++----- coreapi/private.h | 5 --- coreapi/quality_reporting.c | 2 +- coreapi/sal.c | 62 ++++++++++++++++++++++++++---- coreapi/upnp.c | 5 ++- include/sal/sal.h | 9 ++++- mediastreamer2 | 2 +- 13 files changed, 132 insertions(+), 110 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 76b7069b3..f2363af83 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -57,7 +57,7 @@ static void sdp_process(SalOp *h){ strcpy(h->result->addr,h->base.remote_media->addr); h->result->bandwidth=h->base.remote_media->bandwidth; - for(i=0;iresult->n_active_streams;++i){ + for(i=0;iresult);++i){ strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr); h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime; h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth; @@ -368,7 +368,7 @@ static int extract_sdp(belle_sip_message_t* message,belle_sdp_session_descriptio } static int is_media_description_acceptable(SalMediaDescription *md){ - if (md->n_total_streams==0){ + if (md->nb_streams==0){ ms_warning("Media description does not define any stream."); return FALSE; } diff --git a/coreapi/bellesip_sal/sal_sdp.c b/coreapi/bellesip_sal/sal_sdp.c index 268fbc480..90f38af19 100644 --- a/coreapi/bellesip_sal/sal_sdp.c +++ b/coreapi/bellesip_sal/sal_sdp.c @@ -344,7 +344,7 @@ belle_sdp_session_description_t * media_description_to_sdp ( const SalMediaDescr belle_sdp_session_description_add_attribute(session_desc, create_rtcp_xr_attribute(&desc->rtcp_xr)); } - for ( i=0; in_total_streams; i++ ) { + for ( i=0; inb_streams; i++ ) { stream_description_to_sdp(session_desc, desc, &desc->streams[i]); } return session_desc; @@ -616,7 +616,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, const char* value; const char *mtype,*proto; - stream=&md->streams[md->n_total_streams]; + stream=&md->streams[md->nb_streams]; media=belle_sdp_media_description_get_media ( media_desc ); memset ( stream,0,sizeof ( *stream ) ); @@ -642,9 +642,6 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, stream->rtp_port=belle_sdp_media_get_media_port ( media ); - if ( stream->rtp_port > 0 ) - md->n_active_streams++; - mtype = belle_sdp_media_get_media_type ( media ); if ( strcasecmp ( "audio", mtype ) == 0 ) { stream->type=SalAudio; @@ -708,7 +705,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, stream->rtcp_xr = md->rtcp_xr; // Use session parameters if no stream parameters are defined sdp_parse_media_rtcp_xr_parameters(media_desc, &stream->rtcp_xr); - md->n_total_streams++; + md->nb_streams++; return stream; } @@ -720,8 +717,7 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S belle_sdp_session_name_t *sname; const char* value; - desc->n_active_streams = 0; - desc->n_total_streams = 0; + desc->nb_streams = 0; desc->dir = SalStreamSendRecv; if ( ( cnx=belle_sdp_session_description_get_connection ( session_desc ) ) && belle_sdp_connection_get_address ( cnx ) ) { @@ -762,8 +758,8 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S for ( media_desc_it=belle_sdp_session_description_get_media_descriptions ( session_desc ) ; media_desc_it!=NULL ; media_desc_it=media_desc_it->next ) { - if (desc->n_total_streams==SAL_MEDIA_DESCRIPTION_MAX_STREAMS){ - ms_warning("Cannot convert mline at position [%i] from SDP to SalMediaDescription",desc->n_total_streams); + if (desc->nb_streams==SAL_MEDIA_DESCRIPTION_MAX_STREAMS){ + ms_warning("Cannot convert mline at position [%i] from SDP to SalMediaDescription",desc->nb_streams); break; } media_desc=BELLE_SDP_MEDIA_DESCRIPTION ( media_desc_it->data ); diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 9b427506b..16b2b9d92 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -47,7 +47,8 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c char *rtp_addr, *rtcp_addr; int i; - for (i = 0; i < new_md->n_active_streams; i++) { + for (i = 0; i < new_md->nb_streams; i++) { + if (!sal_stream_description_active(&new_md->streams[i])) continue; if (new_md->streams[i].type == SalAudio) { new_audiodesc = &new_md->streams[i]; } else if (new_md->streams[i].type == SalVideo) { @@ -108,7 +109,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia ms_error("linphone_core_update_streams() called with null media description"); return; } - if (call->biggestdesc==NULL || new_md->n_total_streams>call->biggestdesc->n_total_streams){ + if (call->biggestdesc==NULL || new_md->nb_streams>call->biggestdesc->nb_streams){ /*we have been offered and now are ready to proceed, or we added a new stream*/ /*store the media description to remember the mapping of calls*/ if (call->biggestdesc){ @@ -312,7 +313,8 @@ static void try_early_media_forking(LinphoneCall *call, SalMediaDescription *md) SalStreamDescription *ref_stream,*new_stream; ms_message("Early media response received from another branch, checking if media can be forked to this new destination."); - for (i=0;in_active_streams;++i){ + for (i=0;inb_streams;++i){ + if (!sal_stream_description_active(&cur_md->streams[i])) continue; ref_stream=&cur_md->streams[i]; new_stream=&md->streams[i]; if (ref_stream->type==new_stream->type && ref_stream->payloads && new_stream->payloads){ @@ -738,7 +740,8 @@ static void call_failure(SalOp *op){ || (call->state == LinphoneCallOutgoingRinging) /* Push notification case */ || (call->state == LinphoneCallOutgoingEarlyMedia)) { int i; - for (i = 0; i < call->localdesc->n_active_streams; i++) { + for (i = 0; i < call->localdesc->nb_streams; i++) { + if (!sal_stream_description_active(&call->localdesc->streams[i])) continue; if (call->params.media_encryption == LinphoneMediaEncryptionSRTP) { if (call->params.avpf_enabled == TRUE) { if (i == 0) ms_message("Retrying call [%p] with SAVP", call); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 7fa8b5fc5..d856a4383 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -254,11 +254,12 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){ int i; - for (i = 0; i < md->n_active_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; if ((md->streams[i].type == SalAudio) && (ac->port != 0)) { strcpy(md->streams[0].rtp_addr,ac->addr); md->streams[0].rtp_port=ac->port; - if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || md->n_active_streams==1){ + if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || sal_media_description_get_nb_active_streams(md)==1){ strcpy(md->addr,ac->addr); } } @@ -301,9 +302,10 @@ static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){ SalMediaDescription *old_md=call->localdesc; bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",1); - for(i=0; in_active_streams; i++) { - if (stream_description_has_srtp(&md->streams[i]) == TRUE) { - if (keep_srtp_keys && old_md && stream_description_has_srtp(&old_md->streams[i]) == TRUE){ + for(i=0; inb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; + if (sal_stream_description_has_srtp(&md->streams[i]) == TRUE) { + if (keep_srtp_keys && old_md && sal_stream_description_has_srtp(&old_md->streams[i]) == TRUE){ int j; ms_message("Keeping same crypto keys."); for(j=0;jn_active_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; for (pt_it = md->streams[i].payloads; pt_it != NULL; pt_it = pt_it->next) { pt = (PayloadType *)pt_it->data; if (call->params.avpf_enabled == TRUE) { @@ -363,7 +366,8 @@ static void setup_rtcp_xr(LinphoneCall *call, SalMediaDescription *md) { } md->rtcp_xr.voip_metrics_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_xr_voip_metrics_enabled", 0); } - for (i = 0; i < md->n_active_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; memcpy(&md->streams[i].rtcp_xr, &md->rtcp_xr, sizeof(md->streams[i].rtcp_xr)); } } @@ -385,6 +389,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * PayloadType *pt; SalMediaDescription *old_md=call->localdesc; int i; + int nb_active_streams = 0; const char *me; SalMediaDescription *md=sal_media_description_new(); LinphoneAddress *addr; @@ -401,7 +406,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * md->session_id=(old_md ? old_md->session_id : (rand() & 0xfff)); md->session_ver=(old_md ? (old_md->session_ver+1) : (rand() & 0xfff)); - md->n_total_streams=(call->biggestdesc ? call->biggestdesc->n_total_streams : 1); + md->nb_streams=(call->biggestdesc ? call->biggestdesc->nb_streams : 1); strncpy(md->addr,local_ip,sizeof(md->addr)); strncpy(md->username,linphone_address_get_username(addr),sizeof(md->username)); @@ -412,7 +417,6 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * else md->bandwidth=linphone_core_get_download_bandwidth(lc); /*set audio capabilities */ - md->n_active_streams=1; strncpy(md->streams[0].rtp_addr,local_ip,sizeof(md->streams[0].rtp_addr)); strncpy(md->streams[0].rtcp_addr,local_ip,sizeof(md->streams[0].rtcp_addr)); strncpy(md->streams[0].name,"Audio",sizeof(md->streams[0].name)-1); @@ -428,9 +432,9 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * pt=payload_type_clone(rtp_profile_get_payload_from_mime(lc->default_profile,"telephone-event")); l=ms_list_append(l,pt); md->streams[0].payloads=l; + nb_active_streams++; if (call->params.has_video){ - md->n_active_streams++; strncpy(md->streams[0].name,"Video",sizeof(md->streams[0].name)-1); md->streams[1].rtp_port=call->media_ports[1].rtp_port; md->streams[1].rtcp_port=call->media_ports[1].rtcp_port; @@ -438,12 +442,14 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * md->streams[1].type=SalVideo; l=make_codec_list(lc,lc->codecs_conf.video_codecs,0,NULL,-1); md->streams[1].payloads=l; + nb_active_streams++; } - if (md->n_total_streams < md->n_active_streams) - md->n_total_streams = md->n_active_streams; + + if (md->nb_streams < nb_active_streams) + md->nb_streams = nb_active_streams; /* Deactivate inactive streams. */ - for (i = md->n_active_streams; i < md->n_total_streams; i++) { + for (i = nb_active_streams; i < md->nb_streams; i++) { md->streams[i].rtp_port = 0; md->streams[i].rtcp_port = 0; md->streams[i].proto = call->biggestdesc->streams[i].proto; @@ -725,8 +731,8 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro call->params.has_video &= linphone_core_media_description_contains_video_stream(md); /* Handle AVPF and SRTP. */ - call->params.avpf_enabled = media_description_has_avpf(md); - if ((media_description_has_srtp(md) == TRUE) && (media_stream_srtp_supported() == TRUE)) { + call->params.avpf_enabled = sal_media_description_has_avpf(md); + if ((sal_media_description_has_srtp(md) == TRUE) && (media_stream_srtp_supported() == TRUE)) { call->params.media_encryption = LinphoneMediaEncryptionSRTP; } } @@ -1062,12 +1068,12 @@ const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call){ for (i = 0; i < nb_video_streams; i++) { sd = sal_media_description_get_active_stream_of_type(md, SalVideo, i); - if (is_video_active(sd) == TRUE) cp->has_video = TRUE; - if (stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; + if (sal_stream_description_active(sd) == TRUE) cp->has_video = TRUE; + if (sal_stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; } for (i = 0; i < nb_audio_streams; i++) { sd = sal_media_description_get_active_stream_of_type(md, SalAudio, i); - if (stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; + if (sal_stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; } if (!cp->has_video){ if (md->bandwidth>0 && md->bandwidth<=linphone_core_get_edge_bw(call->core)){ @@ -1565,7 +1571,7 @@ static void _linphone_call_prepare_ice_for_stream(LinphoneCall *call, int stream cl=ice_session_check_list(call->ice_session, stream_index); if (cl == NULL && create_checklist) { cl=ice_check_list_new(); - ice_session_add_check_list(call->ice_session, cl); + ice_session_add_check_list(call->ice_session, cl, stream_index); ms_message("Created new ICE check list for stream [%i]",stream_index); } if (cl){ @@ -2044,7 +2050,7 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna call->current_params.record_file=ms_strdup(call->params.record_file); } /* valid local tags are > 0 */ - if (stream_description_has_srtp(stream) == TRUE) { + if (sal_stream_description_has_srtp(stream) == TRUE) { local_st_desc=sal_media_description_find_stream(call->localdesc,stream->proto,SalAudio); crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, stream->crypto_local_tag); @@ -2161,7 +2167,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna cam=get_nowebcam_device(); } if (!is_inactive){ - if (stream_description_has_srtp(vstream) == TRUE) { + if (sal_stream_description_has_srtp(vstream) == TRUE) { int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, vstream->crypto_local_tag); if (crypto_idx >= 0) { media_stream_set_srtp_recv_key(&call->videostream->ms,vstream->crypto[0].algo,vstream->crypto[0].master_key); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 360a69725..afa7a7265 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2977,7 +2977,7 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){ } bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md){ - return linphone_core_is_media_encryption_mandatory(lc) && linphone_core_get_media_encryption(lc)==LinphoneMediaEncryptionSRTP && !media_description_has_srtp(md); + return linphone_core_is_media_encryption_mandatory(lc) && linphone_core_get_media_encryption(lc)==LinphoneMediaEncryptionSRTP && !sal_media_description_has_srtp(md); } void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){ @@ -3431,8 +3431,8 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, if (md) { call->params.has_video &= linphone_core_media_description_contains_video_stream(md); /* Handle AVPF and SRTP. */ - call->params.avpf_enabled = media_description_has_avpf(md); - if ((media_description_has_srtp(md) == TRUE) && (media_stream_srtp_supported() == TRUE)) { + call->params.avpf_enabled = sal_media_description_has_avpf(md); + if ((sal_media_description_has_srtp(md) == TRUE) && (media_stream_srtp_supported() == TRUE)) { call->params.media_encryption = LinphoneMediaEncryptionSRTP; } } diff --git a/coreapi/misc.c b/coreapi/misc.c index 2a86db03a..43b3a3139 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -711,11 +711,11 @@ void linphone_core_update_local_media_description_from_ice(SalMediaDescription * } strncpy(desc->ice_pwd, ice_session_local_pwd(session), sizeof(desc->ice_pwd)); strncpy(desc->ice_ufrag, ice_session_local_ufrag(session), sizeof(desc->ice_ufrag)); - for (i = 0; i < desc->n_active_streams; i++) { + for (i = 0; i < desc->nb_streams; i++) { SalStreamDescription *stream = &desc->streams[i]; IceCheckList *cl = ice_session_check_list(session, i); nb_candidates = 0; - if (cl == NULL) continue; + if (!sal_stream_description_active(stream) || (cl == NULL)) continue; if (ice_check_list_state(cl) == ICL_Completed) { stream->ice_completed = TRUE; result = ice_check_list_selected_valid_local_candidate(ice_session_check_list(session, i), &rtp_addr, &stream->rtp_port, &rtcp_addr, &stream->rtcp_port); @@ -822,7 +822,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, ice_session_restart(call->ice_session); ice_restarted = TRUE; } else { - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { const SalStreamDescription *stream = &md->streams[i]; IceCheckList *cl = ice_session_check_list(call->ice_session, i); if (cl && (strcmp(stream->rtp_addr, "0.0.0.0") == 0)) { @@ -841,7 +841,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, } ice_session_set_remote_credentials(call->ice_session, md->ice_ufrag, md->ice_pwd); } - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { const SalStreamDescription *stream = &md->streams[i]; IceCheckList *cl = ice_session_check_list(call->ice_session, i); if (cl && (stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) { @@ -857,7 +857,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, } /* Create ICE check lists if needed and parse ICE attributes. */ - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { const SalStreamDescription *stream = &md->streams[i]; IceCheckList *cl = ice_session_check_list(call->ice_session, i); /* @@ -918,10 +918,12 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, } } } - for (i = ice_session_nb_check_lists(call->ice_session); i > md->n_active_streams; i--) { - IceCheckList *removed=ice_session_check_list(call->ice_session, i - 1); - ice_session_remove_check_list(call->ice_session, removed); - clear_ice_check_list(call,removed); + for (i = 0; i < md->nb_streams; i++) { + IceCheckList * cl = ice_session_check_list(call->ice_session, i); + if (!sal_stream_description_active(&md->streams[i]) && (cl != NULL)) { + ice_session_remove_check_list_from_idx(call->ice_session, i); + clear_ice_check_list(call, cl); + } } ice_session_check_mismatch(call->ice_session); } else { @@ -937,7 +939,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md){ int i; - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { if (md->streams[i].type == SalVideo && md->streams[i].rtp_port!=0) return TRUE; } @@ -1520,33 +1522,3 @@ const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc){ lc->rtp_conf.srtp_suites=result; return result; } - -bool_t is_video_active(const SalStreamDescription *sd) { - return (sd->rtp_port != 0) && (sd->dir != SalStreamInactive); -} - -bool_t stream_description_has_avpf(const SalStreamDescription *sd) { - return ((sd->proto == SalProtoRtpAvpf) || (sd->proto == SalProtoRtpSavpf)); -} - -bool_t stream_description_has_srtp(const SalStreamDescription *sd) { - return ((sd->proto == SalProtoRtpSavp) || (sd->proto == SalProtoRtpSavpf)); -} - -bool_t media_description_has_avpf(const SalMediaDescription *md) { - int i; - if (md->n_active_streams == 0) return FALSE; - for (i = 0; i < md->n_active_streams; i++) { - if (stream_description_has_avpf(&md->streams[i]) != TRUE) return FALSE; - } - return TRUE; -} - -bool_t media_description_has_srtp(const SalMediaDescription *md) { - int i; - if (md->n_active_streams == 0) return FALSE; - for (i = 0; i < md->n_active_streams; i++) { - if (stream_description_has_srtp(&md->streams[i]) != TRUE) return FALSE; - } - return TRUE; -} diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index aef918b92..779e7ae65 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -237,7 +237,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer, }else{ result->rtp_port=0; } - if (stream_description_has_srtp(result) == TRUE) { + if (sal_stream_description_has_srtp(result) == TRUE) { /* verify crypto algo */ memset(result->crypto, 0, sizeof(result->crypto)); if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], &result->crypto_local_tag, FALSE)) @@ -263,7 +263,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap, }else{ result->rtp_port=0; } - if (stream_description_has_srtp(result) == TRUE) { + if (sal_stream_description_has_srtp(result) == TRUE) { /* select crypto algo */ memset(result->crypto, 0, sizeof(result->crypto)); if (!match_crypto_algo(local_cap->crypto, remote_offer->crypto, &result->crypto[0], &result->crypto_local_tag, TRUE)) @@ -289,7 +289,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, int i,j; const SalStreamDescription *ls,*rs; - for(i=0,j=0;in_total_streams;++i){ + for(i=0,j=0;inb_streams;++i){ ms_message("Processing for stream %i",i); ls=&local_offer->streams[i]; rs=sal_media_description_find_stream((SalMediaDescription*)remote_answer,ls->proto,ls->type); @@ -303,8 +303,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, } else ms_warning("No matching stream for %i",i); } - result->n_active_streams=j; - result->n_total_streams=local_offer->n_total_streams; + result->nb_streams=local_offer->nb_streams; result->bandwidth=remote_answer->bandwidth; strcpy(result->addr,remote_answer->addr); memcpy(&result->rtcp_xr, &local_offer->rtcp_xr, sizeof(result->rtcp_xr)); @@ -317,7 +316,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, static bool_t local_stream_not_already_used(const SalMediaDescription *result, const SalStreamDescription *stream){ int i; - for(i=0;in_total_streams;++i){ + for(i=0;inb_streams;++i){ const SalStreamDescription *ss=&result->streams[i]; if (strcmp(ss->name,stream->name)==0){ ms_message("video stream already used in answer"); @@ -337,8 +336,9 @@ static bool_t proto_compatible(SalMediaProto local, SalMediaProto remote) { static const SalStreamDescription *find_local_matching_stream(const SalMediaDescription *result, const SalMediaDescription *local_capabilities, const SalStreamDescription *remote_stream){ int i; - for(i=0;in_active_streams;++i){ + for(i=0;inb_streams;++i){ const SalStreamDescription *ss=&local_capabilities->streams[i]; + if (!sal_stream_description_active(ss)) continue; if (ss->type==remote_stream->type && proto_compatible(ss->proto,remote_stream->proto) && local_stream_not_already_used(result,ss)) return ss; } @@ -356,15 +356,13 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities int i; const SalStreamDescription *ls=NULL,*rs; - result->n_active_streams=0; - for(i=0;in_total_streams;++i){ + for(i=0;inb_streams;++i){ rs=&remote_offer->streams[i]; if (rs->proto!=SalProtoOther){ ls=find_local_matching_stream(result,local_capabilities,rs); }else ms_warning("Unknown protocol for mline %i, declining",i); if (ls){ initiate_incoming(ls,rs,&result->streams[i],one_matching_codec); - if (result->streams[i].rtp_port!=0) result->n_active_streams++; // Handle media RTCP XR attribute memset(&result->streams[i].rtcp_xr, 0, sizeof(result->streams[i].rtcp_xr)); @@ -393,7 +391,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities } } } - result->n_total_streams=i; + result->nb_streams=i; strcpy(result->username, local_capabilities->username); strcpy(result->addr,local_capabilities->addr); result->bandwidth=local_capabilities->bandwidth; diff --git a/coreapi/private.h b/coreapi/private.h index b0ddd3047..2b6f8308d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -393,11 +393,6 @@ bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc); LinphoneCall * is_a_linphone_call(void *user_pointer); LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer); -bool_t is_video_active(const SalStreamDescription *sd); -bool_t stream_description_has_avpf(const SalStreamDescription *sd); -bool_t stream_description_has_srtp(const SalStreamDescription *sd); -bool_t media_description_has_avpf(const SalMediaDescription *md); -bool_t media_description_has_srtp(const SalMediaDescription *md); void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description); diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 2fd4229c3..06e42fb43 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -372,7 +372,7 @@ static void send_report(const LinphoneCall* call, reporting_session_report_t * r static const SalStreamDescription * get_media_stream_for_desc(const SalMediaDescription * smd, SalStreamType sal_stream_type) { int count; if (smd != NULL) { - for (count = 0; count < smd->n_total_streams; ++count) { + for (count = 0; count < smd->nb_streams; ++count) { if (smd->streams[count].type == sal_stream_type) { return &smd->streams[count]; } diff --git a/coreapi/sal.c b/coreapi/sal.c index 74d087139..24da751b6 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -84,8 +84,9 @@ void sal_media_description_unref(SalMediaDescription *md){ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, SalMediaProto proto, SalStreamType type){ int i; - for(i=0;in_active_streams;++i){ + for(i=0;inb_streams;++i){ SalStreamDescription *ss=&md->streams[i]; + if (!sal_stream_description_active(ss)) continue; if (ss->proto==proto && ss->type==type) return ss; } return NULL; @@ -94,7 +95,8 @@ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription *md, SalStreamType type) { unsigned int i; unsigned int nb = 0; - for (i = 0; i < md->n_active_streams; ++i) { + for (i = 0; i < md->nb_streams; ++i) { + if (!sal_stream_description_active(&md->streams[i])) continue; if (md->streams[i].type == type) nb++; } return nb; @@ -102,7 +104,8 @@ unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription SalStreamDescription * sal_media_description_get_active_stream_of_type(SalMediaDescription *md, SalStreamType type, unsigned int idx) { unsigned int i; - for (i = 0; i < md->n_active_streams; ++i) { + for (i = 0; i < md->nb_streams; ++i) { + if (!sal_stream_description_active(&md->streams[i])) continue; if (md->streams[i].type == type) { if (idx-- == 0) return &md->streams[i]; } @@ -125,18 +128,28 @@ SalStreamDescription * sal_media_description_find_best_stream(SalMediaDescriptio } bool_t sal_media_description_empty(const SalMediaDescription *md){ - if (md->n_active_streams > 0) return FALSE; + if (sal_media_description_get_nb_active_streams(md) > 0) return FALSE; return TRUE; } void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir){ int i; - for(i=0;in_active_streams;++i){ + for(i=0;inb_streams;++i){ SalStreamDescription *ss=&md->streams[i]; + if (!sal_stream_description_active(ss)) continue; ss->dir=stream_dir; } } +int sal_media_description_get_nb_active_streams(const SalMediaDescription *md) { + int i; + int nb = 0; + for (i = 0; i < md->nb_streams; i++) { + if (sal_stream_description_active(&md->streams[i])) nb++; + } + return nb; +} + static bool_t is_null_address(const char *addr){ return strcmp(addr,"0.0.0.0")==0 || strcmp(addr,"::0")==0; @@ -147,8 +160,9 @@ static bool_t has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){ int i; /* we are looking for at least one stream with requested direction, inactive streams are ignored*/ - for(i=0;in_active_streams;++i){ + for(i=0;inb_streams;++i){ const SalStreamDescription *ss=&md->streams[i]; + if (!sal_stream_description_active(ss)) continue; if (ss->dir==stream_dir) return TRUE; /*compatibility check for phones that only used the null address and no attributes */ if (ss->dir==SalStreamSendRecv && stream_dir==SalStreamSendOnly && (is_null_address(md->addr) || is_null_address(ss->rtp_addr))) @@ -175,6 +189,38 @@ bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir return FALSE; } +bool_t sal_stream_description_active(const SalStreamDescription *sd) { + return (sd->rtp_port > 0); +} + +bool_t sal_stream_description_has_avpf(const SalStreamDescription *sd) { + return ((sd->proto == SalProtoRtpAvpf) || (sd->proto == SalProtoRtpSavpf)); +} + +bool_t sal_stream_description_has_srtp(const SalStreamDescription *sd) { + return ((sd->proto == SalProtoRtpSavp) || (sd->proto == SalProtoRtpSavpf)); +} + +bool_t sal_media_description_has_avpf(const SalMediaDescription *md) { + int i; + if (md->nb_streams == 0) return FALSE; + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; + if (sal_stream_description_has_avpf(&md->streams[i]) != TRUE) return FALSE; + } + return TRUE; +} + +bool_t sal_media_description_has_srtp(const SalMediaDescription *md) { + int i; + if (md->nb_streams == 0) return FALSE; + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; + if (sal_stream_description_has_srtp(&md->streams[i]) != TRUE) return FALSE; + } + return TRUE; +} + /* static bool_t fmtp_equals(const char *p1, const char *p2){ if (p1 && p2 && strcmp(p1,p2)==0) return TRUE; @@ -261,9 +307,9 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD int i; if (strcmp(md1->addr, md2->addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED; - if (md1->n_total_streams != md2->n_total_streams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; + if (md1->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; - for(i = 0; i < md1->n_total_streams; ++i){ + for(i = 0; i < md1->nb_streams; ++i){ result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]); } return result; diff --git a/coreapi/upnp.c b/coreapi/upnp.c index 7feaaa30c..5fcbbe065 100644 --- a/coreapi/upnp.c +++ b/coreapi/upnp.c @@ -731,7 +731,7 @@ int linphone_core_update_upnp_from_remote_media_description(LinphoneCall *call, int i; const SalStreamDescription *stream; - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { stream = &md->streams[i]; if(stream->type == SalAudio) { audio = TRUE; @@ -1058,8 +1058,9 @@ int linphone_core_update_local_media_description_from_upnp(SalMediaDescription * SalStreamDescription *stream; UpnpStream *upnpStream; - for (i = 0; i < desc->n_active_streams; i++) { + for (i = 0; i < desc->nb_streams; i++) { stream = &desc->streams[i]; + if (!sal_stream_description_active(stream)) continue; upnpStream = NULL; if(stream->type == SalAudio) { upnpStream = session->audio; diff --git a/include/sal/sal.h b/include/sal/sal.h index d86dcc91e..e9719fc7b 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -215,8 +215,7 @@ typedef struct SalMediaDescription{ char name[64]; char addr[64]; char username[64]; - int n_active_streams; - int n_total_streams; + int nb_streams; int bandwidth; unsigned int session_ver; unsigned int session_id; @@ -259,6 +258,12 @@ SalStreamDescription * sal_media_description_get_active_stream_of_type(SalMediaD SalStreamDescription * sal_media_description_find_secure_stream_of_type(SalMediaDescription *md, SalStreamType type); SalStreamDescription * sal_media_description_find_best_stream(SalMediaDescription *md, SalStreamType type); void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir); +bool_t sal_stream_description_active(const SalStreamDescription *sd); +bool_t sal_stream_description_has_avpf(const SalStreamDescription *sd); +bool_t sal_stream_description_has_srtp(const SalStreamDescription *sd); +bool_t sal_media_description_has_avpf(const SalMediaDescription *md); +bool_t sal_media_description_has_srtp(const SalMediaDescription *md); +int sal_media_description_get_nb_active_streams(const SalMediaDescription *md); /*this structure must be at the first byte of the SalOp structure defined by implementors*/ diff --git a/mediastreamer2 b/mediastreamer2 index ff45699c7..7bf89d430 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit ff45699c79c09eb2f57aa07d8e63c20e66e35073 +Subproject commit 7bf89d4302afb266bb359d7af8c16907ae8c327e