Correctly handle negotiation of RTP profiles (APV/APVF/SAVP/SAVPF).

This commit is contained in:
Ghislain MARY 2014-06-04 11:59:50 +02:00
parent ba0a032433
commit dafdbb3444
5 changed files with 53 additions and 31 deletions

View file

@ -266,8 +266,8 @@ static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){
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 (is_encryption_active(&md->streams[i]) == TRUE) {
if (keep_srtp_keys && old_md && is_encryption_active(&old_md->streams[i]) == TRUE){
if (stream_description_has_srtp(&md->streams[i]) == TRUE) {
if (keep_srtp_keys && old_md && 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){
@ -687,6 +687,12 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
// It is licit to receive an INVITE without SDP
// In this case WE chose the media parameters according to policy.
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.media_encryption = LinphoneMediaEncryptionSRTP;
}
}
fpol=linphone_core_get_firewall_policy(call->core);
/*create the ice session now if ICE is required*/
@ -1015,11 +1021,11 @@ 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 (is_encryption_active(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP;
if (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 (is_encryption_active(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP;
if (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)){
@ -1992,7 +1998,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 (is_encryption_active(stream) == TRUE) {
if (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);
@ -2109,7 +2115,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
cam=get_nowebcam_device();
}
if (!is_inactive){
if (is_encryption_active(vstream) == TRUE) {
if (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);

View file

@ -2973,21 +2973,8 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){
return FALSE;
}
bool_t linphone_core_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++){
const SalStreamDescription *sd=&md->streams[i];
if (is_encryption_active(sd) != TRUE){
return FALSE;
}
}
return TRUE;
}
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 && !linphone_core_media_description_has_srtp(md);
return linphone_core_is_media_encryption_mandatory(lc) && linphone_core_get_media_encryption(lc)==LinphoneMediaEncryptionSRTP && !media_description_has_srtp(md);
}
void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
@ -3432,7 +3419,14 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
_linphone_call_params_copy(&call->params,params);
// There might not be a md if the INVITE was lacking an SDP
// In this case we use the parameters as is.
if (md) call->params.has_video &= linphone_core_media_description_contains_video_stream(md);
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.media_encryption = LinphoneMediaEncryptionSRTP;
}
}
linphone_call_make_local_media_description(lc,call);
sal_call_set_local_media_description(call->op,call->localdesc);
sal_op_set_sent_custom_header(call->op,params->custom_headers);

View file

@ -1524,6 +1524,28 @@ bool_t is_video_active(const SalStreamDescription *sd) {
return (sd->rtp_port != 0) && (sd->dir != SalStreamInactive);
}
bool_t is_encryption_active(const SalStreamDescription *sd) {
return ((sd->proto == SalProtoRtpSavpf) || (sd->proto == SalProtoRtpSavp));
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;
}

View file

@ -237,7 +237,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
}else{
result->rtp_port=0;
}
if (is_encryption_active(result) == TRUE) {
if (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 (is_encryption_active(result) == TRUE) {
if (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))
@ -330,10 +330,8 @@ static bool_t local_stream_not_already_used(const SalMediaDescription *result, c
/*in answering mode, we consider that if we are able to make AVPF/SAVP/SAVPF, then we can do AVP as well*/
static bool_t proto_compatible(SalMediaProto local, SalMediaProto remote) {
if (local == remote) return TRUE;
if ((remote == SalProtoRtpAvpf) && (local == SalProtoRtpSavpf))
return TRUE;
if ((remote == SalProtoRtpAvp) && ((local == SalProtoRtpSavp) || (local == SalProtoRtpAvpf) || (local == SalProtoRtpSavpf)))
return TRUE;
if ((remote == SalProtoRtpAvp) && ((local == SalProtoRtpSavp) || (local == SalProtoRtpSavpf))) return TRUE;
if ((remote == SalProtoRtpAvpf) && (local == SalProtoRtpSavpf)) return TRUE;
return FALSE;
}

View file

@ -337,7 +337,6 @@ void linphone_call_stats_fill(LinphoneCallStats *stats, MediaStream *ms, OrtpEve
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session);
void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md);
bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md);
bool_t linphone_core_media_description_has_srtp(const SalMediaDescription *md);
void linphone_core_send_initial_subscribes(LinphoneCore *lc);
void linphone_core_write_friends_config(LinphoneCore* lc);
@ -393,7 +392,10 @@ 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 is_encryption_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);