mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-03 20:46:28 +00:00
Handle conversion between media description and ice session.
This commit is contained in:
parent
6f2853c8a0
commit
5742b453cd
6 changed files with 151 additions and 10 deletions
|
|
@ -261,10 +261,9 @@ static void call_accepted(SalOp *op){
|
|||
return ;
|
||||
}
|
||||
|
||||
if (call->ice_session == NULL) {
|
||||
/* Ensure the ICE check list pointers for the call streams are resetted to prevent crashes */
|
||||
if (call->audiostream != NULL) call->audiostream->ice_check_list = NULL;
|
||||
if (call->videostream != NULL) call->videostream->ice_check_list = NULL;
|
||||
/* Handle remote ICE attributes if any. */
|
||||
if (call->ice_session != NULL) {
|
||||
linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(op));
|
||||
}
|
||||
|
||||
md=sal_call_get_final_media_description(op);
|
||||
|
|
|
|||
|
|
@ -247,8 +247,7 @@ static SalMediaDescription *_create_local_media_description(LinphoneCore *lc, Li
|
|||
md->streams[i].crypto[1].algo = 0;
|
||||
md->streams[i].crypto[2].algo = 0;
|
||||
}
|
||||
if ((call->dir == LinphoneCallOutgoing) && (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce)
|
||||
&& (call->ice_session != NULL) && (ice_session_check_list(call->ice_session, i) == NULL)) {
|
||||
if ((linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) && (call->ice_session != NULL) && (ice_session_check_list(call->ice_session, i) == NULL)) {
|
||||
ice_session_add_check_list(call->ice_session, ice_check_list_new());
|
||||
}
|
||||
}
|
||||
|
|
@ -390,6 +389,9 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
call->camera_active=call->params.has_video;
|
||||
switch (linphone_core_get_firewall_policy(call->core)) {
|
||||
case LinphonePolicyUseIce:
|
||||
call->ice_session = ice_session_new();
|
||||
ice_session_set_role(call->ice_session, IR_Controlled);
|
||||
linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(op));
|
||||
linphone_call_init_media_streams(call);
|
||||
linphone_call_start_media_streams_for_ice_gathering(call);
|
||||
if (linphone_core_gather_ice_candidates(call->core,call)<0) {
|
||||
|
|
@ -402,7 +404,6 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
|
|||
linphone_core_run_stun_tests(call->core,call);
|
||||
/* No break to also destroy ice session in this case. */
|
||||
default:
|
||||
linphone_call_delete_ice_session(call);
|
||||
break;
|
||||
}
|
||||
discover_mtu(lc,linphone_address_get_domain(from));
|
||||
|
|
|
|||
|
|
@ -2123,6 +2123,8 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro
|
|||
audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard);
|
||||
if (!lc->sip_conf.sdp_200_ack){
|
||||
call->media_pending=TRUE;
|
||||
if (call->ice_session != NULL)
|
||||
linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
}
|
||||
real_url=linphone_address_as_string(call->log->to);
|
||||
|
|
@ -2379,9 +2381,9 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
bool_t propose_early_media=lp_config_get_int(lc->config,"sip","incoming_calls_early_media",FALSE);
|
||||
const char *ringback_tone=linphone_core_get_remote_ringback_tone (lc);
|
||||
|
||||
/* Regenerate final media description to include all ICE candidates. */
|
||||
if (call->ice_session != NULL)
|
||||
linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
|
||||
md=sal_call_get_final_media_description(call->op);
|
||||
|
||||
if (md && sal_media_description_empty(md)){
|
||||
sal_call_decline(call->op,SalReasonMedia,NULL);
|
||||
linphone_call_unref(call);
|
||||
|
|
@ -2464,7 +2466,9 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho
|
|||
call->params=*params;
|
||||
call->camera_active=call->params.has_video;
|
||||
update_local_media_description(lc,call);
|
||||
|
||||
if (call->ice_session != NULL)
|
||||
linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
|
||||
|
||||
if (params->in_conference){
|
||||
subject="Conference";
|
||||
}else{
|
||||
|
|
@ -2548,6 +2552,10 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const
|
|||
}
|
||||
call->camera_active=call->params.has_video;
|
||||
update_local_media_description(lc,call);
|
||||
if (call->ice_session != NULL) {
|
||||
linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
|
||||
linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(call->op));
|
||||
}
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
sal_call_accept(call->op);
|
||||
md=sal_call_get_final_media_description(call->op);
|
||||
|
|
|
|||
122
coreapi/misc.c
122
coreapi/misc.c
|
|
@ -605,6 +605,128 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void linphone_core_update_local_media_description_from_ice(SalMediaDescription *desc, IceSession *session)
|
||||
{
|
||||
IceSessionState session_state = ice_session_state(session);
|
||||
int i, j;
|
||||
|
||||
if (session_state == IS_Completed) desc->ice_completed = TRUE;
|
||||
else desc->ice_completed = FALSE;
|
||||
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->nstreams; i++) {
|
||||
SalStreamDescription *stream = &desc->streams[i];
|
||||
IceCheckList *cl = ice_session_check_list(session, i);
|
||||
if (cl == NULL) continue;
|
||||
if ((strlen(ice_check_list_local_pwd(cl)) != strlen(desc->ice_pwd)) || (strcmp(ice_check_list_local_pwd(cl), desc->ice_pwd)))
|
||||
strncpy(stream->ice_pwd, ice_check_list_local_pwd(cl), sizeof(stream->ice_pwd));
|
||||
else
|
||||
memset(stream->ice_pwd, 0, sizeof(stream->ice_pwd));
|
||||
if ((strlen(ice_check_list_local_ufrag(cl)) != strlen(desc->ice_ufrag)) || (strcmp(ice_check_list_local_ufrag(cl), desc->ice_ufrag)))
|
||||
strncpy(stream->ice_ufrag, ice_check_list_local_ufrag(cl), sizeof(stream->ice_ufrag));
|
||||
else
|
||||
memset(stream->ice_pwd, 0, sizeof(stream->ice_pwd));
|
||||
if ((cl->state == ICL_Running) || (cl->state == ICL_Completed)) {
|
||||
memset(stream->ice_candidates, 0, sizeof(stream->ice_candidates));
|
||||
for (j = 0; j < ms_list_size(cl->local_candidates); j++) {
|
||||
SalIceCandidate *sal_candidate = &stream->ice_candidates[j];
|
||||
IceCandidate *ice_candidate = ms_list_nth_data(cl->local_candidates, j);
|
||||
const char *default_addr = NULL;
|
||||
int default_port = 0;
|
||||
if (ice_candidate->componentID == 1) {
|
||||
default_addr = stream->rtp_addr;
|
||||
default_port = stream->rtp_port;
|
||||
} else if (ice_candidate->componentID == 2) {
|
||||
default_addr = stream->rtcp_addr;
|
||||
default_port = stream->rtcp_port;
|
||||
} else continue;
|
||||
if (default_addr[0] == '\0') default_addr = desc->addr;
|
||||
/* Only include the candidates matching the default destination for each component of the stream if the state is Completed as specified in RFC5245 section 9.1.2.2. */
|
||||
if ((cl->state == ICL_Completed)
|
||||
&& !((ice_candidate->taddr.port == default_port) && (strlen(ice_candidate->taddr.ip) == strlen(default_addr)) && (strcmp(ice_candidate->taddr.ip, default_addr) == 0)))
|
||||
continue;
|
||||
strncpy(sal_candidate->foundation, ice_candidate->foundation, sizeof(sal_candidate->foundation));
|
||||
sal_candidate->componentID = ice_candidate->componentID;
|
||||
sal_candidate->priority = ice_candidate->priority;
|
||||
strncpy(sal_candidate->type, ice_candidate_type(ice_candidate), sizeof(sal_candidate->type));
|
||||
strncpy(sal_candidate->addr, ice_candidate->taddr.ip, sizeof(sal_candidate->addr));
|
||||
sal_candidate->port = ice_candidate->taddr.port;
|
||||
if ((ice_candidate->base != NULL) && (ice_candidate->base != ice_candidate)) {
|
||||
strncpy(sal_candidate->raddr, ice_candidate->base->taddr.ip, sizeof(sal_candidate->raddr));
|
||||
sal_candidate->rport = ice_candidate->base->taddr.port;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((cl->state == ICL_Completed) && (ice_session_role(session) == IR_Controlling)) {
|
||||
const char *rtp_addr, *rtcp_addr;
|
||||
int rtp_port, rtcp_port;
|
||||
memset(stream->ice_remote_candidates, 0, sizeof(stream->ice_remote_candidates));
|
||||
ice_check_list_nominated_valid_remote_candidate(cl, &rtp_addr, &rtp_port, &rtcp_addr, &rtcp_port);
|
||||
strncpy(stream->ice_remote_candidates[0].addr, rtp_addr, sizeof(stream->ice_remote_candidates[0].addr));
|
||||
stream->ice_remote_candidates[0].port = rtp_port;
|
||||
strncpy(stream->ice_remote_candidates[1].addr, rtcp_addr, sizeof(stream->ice_remote_candidates[1].addr));
|
||||
stream->ice_remote_candidates[1].port = rtcp_port;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, const SalMediaDescription *md)
|
||||
{
|
||||
if ((md->ice_pwd[0] != '\0') && (md->ice_ufrag[0] != '\0')) {
|
||||
int i, j;
|
||||
ice_session_set_remote_credentials(call->ice_session, md->ice_ufrag, md->ice_pwd);
|
||||
for (i = 0; i < md->nstreams; i++) {
|
||||
const SalStreamDescription *stream = &md->streams[i];
|
||||
IceCheckList *cl = ice_session_check_list(call->ice_session, i);
|
||||
if (cl == NULL) {
|
||||
cl = ice_check_list_new();
|
||||
ice_session_add_check_list(call->ice_session, cl);
|
||||
switch (stream->type) {
|
||||
case SalAudio:
|
||||
if (call->audiostream != NULL) call->audiostream->ice_check_list = cl;
|
||||
break;
|
||||
case SalVideo:
|
||||
if (call->videostream != NULL) call->videostream->ice_check_list = cl;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (stream->ice_mismatch == TRUE) {
|
||||
ice_check_list_set_state(cl, ICL_Failed);
|
||||
} else {
|
||||
if ((stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0'))
|
||||
ice_check_list_set_remote_credentials(cl, stream->ice_ufrag, stream->ice_pwd);
|
||||
for (j = 0; j < SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES; j++) {
|
||||
const SalIceCandidate *candidate = &stream->ice_candidates[j];
|
||||
bool_t default_candidate = FALSE;
|
||||
const char *addr = NULL;
|
||||
int port = 0;
|
||||
if (candidate->addr[0] == '\0') break;
|
||||
if (candidate->componentID == 1) {
|
||||
addr = stream->rtp_addr;
|
||||
port = stream->rtp_port;
|
||||
}
|
||||
else if (candidate->componentID == 2) {
|
||||
addr = stream->rtcp_addr;
|
||||
port = stream->rtcp_port;
|
||||
}
|
||||
if (addr && (candidate->port == port) && (strlen(candidate->addr) == strlen(addr)) && (strcmp(candidate->addr, addr) == 0))
|
||||
default_candidate = TRUE;
|
||||
ice_add_remote_candidate(cl, candidate->type, candidate->addr, candidate->port, candidate->componentID,
|
||||
candidate->priority, candidate->foundation, default_candidate);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = ice_session_nb_check_lists(call->ice_session); i > md->nstreams; i--) {
|
||||
ice_session_remove_check_list(call->ice_session, ice_session_check_list(call->ice_session, i - 1));
|
||||
}
|
||||
}
|
||||
if ((ice_session_state(call->ice_session) == IS_Failed) || (ice_session_nb_check_lists(call->ice_session) == 0)) {
|
||||
linphone_call_delete_ice_session(call);
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneCall * is_a_linphone_call(void *user_pointer){
|
||||
LinphoneCall *call=(LinphoneCall*)user_pointer;
|
||||
if (call==NULL) return NULL;
|
||||
|
|
|
|||
|
|
@ -253,6 +253,11 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
|
|||
result->rtp_port = 0;
|
||||
|
||||
}
|
||||
strcpy(result->ice_pwd, local_cap->ice_pwd);
|
||||
strcpy(result->ice_ufrag, local_cap->ice_ufrag);
|
||||
result->ice_mismatch = local_cap->ice_mismatch;
|
||||
memcpy(result->ice_candidates, local_cap->ice_candidates, sizeof(result->ice_candidates));
|
||||
memcpy(result->ice_remote_candidates, local_cap->ice_remote_candidates, sizeof(result->ice_remote_candidates));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -321,5 +326,9 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
|
|||
result->bandwidth=local_capabilities->bandwidth;
|
||||
result->session_ver=local_capabilities->session_ver;
|
||||
result->session_id=local_capabilities->session_id;
|
||||
strcpy(result->ice_pwd, local_capabilities->ice_pwd);
|
||||
strcpy(result->ice_ufrag, local_capabilities->ice_ufrag);
|
||||
result->ice_lite = local_capabilities->ice_lite;
|
||||
result->ice_completed = local_capabilities->ice_lite;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -221,6 +221,8 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc);
|
|||
void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt);
|
||||
void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call);
|
||||
int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call);
|
||||
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);
|
||||
|
||||
void linphone_core_send_initial_subscribes(LinphoneCore *lc);
|
||||
void linphone_core_write_friends_config(LinphoneCore* lc);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue