Commit 6f95bbc5 authored by Ghislain MARY's avatar Ghislain MARY
Browse files

Fix bug 0001279: Wrong usage of n_active_streams in the media descriptions.

Inactive streams are now allowed between active streams in the SDP.
parent 0b46ef52
......@@ -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;i<h->result->n_active_streams;++i){
for(i=0;i<sal_media_description_get_nb_active_streams(h->result);++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;
}
......
......@@ -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; i<desc->n_total_streams; i++ ) {
for ( i=0; i<desc->nb_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 );
......
......@@ -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;i<cur_md->n_active_streams;++i){
for (i=0;i<cur_md->nb_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);
......
......@@ -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; i<md->n_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; i<md->nb_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;j<SAL_CRYPTO_ALGO_MAX;++j){
......@@ -325,7 +327,8 @@ static void setup_rtcp_fb(LinphoneCall *call, SalMediaDescription *md) {
PayloadTypeAvpfParams avpf_params;
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;
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);
......
......@@ -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;
}
}
......
......@@ -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;
}
......@@ -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;i<local_offer->n_total_streams;++i){
for(i=0,j=0;i<local_offer->nb_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;i<result->n_total_streams;++i){
for(i=0;i<result->nb_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;i<local_capabilities->n_active_streams;++i){
for(i=0;i<local_capabilities->nb_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;i<remote_offer->n_total_streams;++i){
for(i=0;i<remote_offer->nb_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;
......
......@@ -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);
......
......@@ -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];
}
......
......@@ -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;i<md->n_active_streams;++i){
for(i=0;i<md->nb_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;i<md->n_active_streams;++i){
for(i=0;i<md->nb_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;i<md->n_active_streams;++i){
for(i=0;i<md->nb_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;