Esempio n. 1
0
static void update_ip(LinphoneCall * call, int stats_type) {
	SalStreamType sal_stream_type = stats_type == LINPHONE_CALL_STATS_AUDIO ? SalAudio : stats_type == LINPHONE_CALL_STATS_VIDEO ? SalVideo : SalText;
	const SalStreamDescription * local_desc = get_media_stream_for_desc(call->localdesc, sal_stream_type);
	const SalStreamDescription * remote_desc = get_media_stream_for_desc(sal_call_get_remote_media_description(call->op), sal_stream_type);

	if (local_desc != NULL) {
		/*since this function might be called for video stream AFTER it has been uninitialized, local description might
		be invalid. In any other case, IP/port should be always filled and valid*/
		if (strlen(local_desc->rtp_addr) > 0) {
			call->log->reporting.reports[stats_type]->info.local_addr.port = local_desc->rtp_port;
			STR_REASSIGN(call->log->reporting.reports[stats_type]->info.local_addr.ip, ms_strdup(local_desc->rtp_addr));
		}
	}

	if (remote_desc != NULL) {
		/*port is always stored in stream description struct*/
		call->log->reporting.reports[stats_type]->info.remote_addr.port = remote_desc->rtp_port;

		/*for IP it can be not set if we are using a direct route*/
		if (strlen(remote_desc->rtp_addr) > 0) {
			STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(remote_desc->rtp_addr));
		} else {
			STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(sal_call_get_remote_media_description(call->op)->addr));
		}
	}
}
Esempio n. 2
0
/* this callback is called when an incoming re-INVITE modifies the session*/
static void call_updating(SalOp *op){
	LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
	LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
	SalMediaDescription *rmd=sal_call_get_remote_media_description(op);

	if (rmd==NULL){
		/* case of a reINVITE without SDP */
		call_accept_update(lc,call);
		call->expect_media_in_ack=TRUE;
		return;
	}

	switch(call->state){
		case LinphoneCallPausedByRemote:
			if (sal_media_description_has_dir(rmd,SalStreamSendRecv) || sal_media_description_has_dir(rmd,SalStreamRecvOnly)){
				call_resumed(lc,call);
			}else call_paused_by_remote(lc,call);
		break;
		case LinphoneCallStreamsRunning:
		case LinphoneCallConnected:
			if (sal_media_description_has_dir(rmd,SalStreamSendOnly) || sal_media_description_has_dir(rmd,SalStreamInactive)){
				call_paused_by_remote(lc,call);
			}else{
				call_updated_by_remote(lc,call);
			}
		break;
		default:
			call_accept_update(lc,call);
	}
}
Esempio n. 3
0
static void call_accept_update(LinphoneCore *lc, LinphoneCall *call){
	SalMediaDescription *md;
	SalMediaDescription *rmd=sal_call_get_remote_media_description(call->op);
	if (rmd!=NULL && call->ice_session!=NULL) {
		linphone_core_update_ice_from_remote_media_description(call,rmd);
		linphone_core_update_local_media_description_from_ice(call->localdesc,call->ice_session);
	}
#ifdef BUILD_UPNP
	if(call->upnp_session != NULL) {
		linphone_core_update_upnp_from_remote_media_description(call, rmd);
		linphone_core_update_local_media_description_from_upnp(call->localdesc,call->upnp_session);
	}
#endif //BUILD_UPNP
	linphone_call_update_remote_session_id_and_ver(call);
	sal_call_accept(call->op);
	md=sal_call_get_final_media_description(call->op);
	if (md && !sal_media_description_empty(md)){
		linphone_core_update_streams(lc,call,md);
	}
}
Esempio n. 4
0
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
	SalMediaDescription *oldmd=call->resultdesc;
	bool_t all_muted=FALSE;
	bool_t send_ringbacktone=FALSE;

	linphone_core_stop_ringing(lc);
	if (!new_md) {
		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){
		/*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){
			sal_media_description_unref(call->biggestdesc);
			call->biggestdesc=NULL;
		}
		if (sal_call_is_offerer(call->op))
			call->biggestdesc=sal_media_description_ref(call->localdesc);
		else
			call->biggestdesc=sal_media_description_ref(sal_call_get_remote_media_description(call->op));
	}
	sal_media_description_ref(new_md);
	call->expect_media_in_ack=FALSE;
	call->resultdesc=new_md;
	if ((call->audiostream && call->audiostream->ms.ticker) || (call->videostream && call->videostream->ms.ticker)){
		/* we already started media: check if we really need to restart it*/
		if (oldmd){
			int md_changed = media_parameters_changed(call, oldmd, new_md);
			if ((md_changed & SAL_MEDIA_DESCRIPTION_CODEC_CHANGED) || call->playing_ringbacktone) {
				ms_message("Media descriptions are different, need to restart the streams.");
			} else {
				if (md_changed == SAL_MEDIA_DESCRIPTION_UNCHANGED) {
					if (call->all_muted){
						ms_message("Early media finished, unmuting inputs...");
						/*we were in early media, now we want to enable real media */
						linphone_call_enable_camera (call,linphone_call_camera_enabled (call));
						if (call->audiostream)
							linphone_core_enable_mic(lc, linphone_core_mic_enabled(lc));
#ifdef VIDEO_ENABLED
						if (call->videostream && call->camera_enabled)
							video_stream_change_camera(call->videostream,lc->video_conf.device );
#endif
					}
					ms_message("No need to restart streams, SDP is unchanged.");
					goto end;
				}else {
					if (md_changed & SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED) {
						ms_message("Network parameters have changed, update them.");
						linphone_core_update_streams_destinations(lc, call, oldmd, new_md);
					}
					if (md_changed & SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED) {
						ms_message("Crypto parameters have changed, update them.");
						linphone_call_update_crypto_parameters(call, oldmd, new_md);
					}
					goto end;
				}
			}
		}
		linphone_call_stop_media_streams (call);
		linphone_call_init_media_streams (call);
	}
	
	if (call->audiostream==NULL){
		/*this happens after pausing the call locally. The streams are destroyed and then we wait the 200Ok to recreate them*/
		linphone_call_init_media_streams (call);
	}
	if (call->state==LinphoneCallIncomingEarlyMedia && linphone_core_get_remote_ringback_tone (lc)!=NULL){
		send_ringbacktone=TRUE;
	}
	if (call->state==LinphoneCallIncomingEarlyMedia ||
		(call->state==LinphoneCallOutgoingEarlyMedia && !call->params.real_early_media)){
		all_muted=TRUE;
	}
	linphone_call_start_media_streams(call,all_muted,send_ringbacktone);
	if (call->state==LinphoneCallPausing && call->paused_by_app && ms_list_size(lc->calls)==1){
		linphone_core_play_named_tone(lc,LinphoneToneCallOnHold);
	}
	end:
	if (oldmd) 
		sal_media_description_unref(oldmd);
	
}
Esempio n. 5
0
/*
 * could be reach :
 *  - when the call is accepted
 *  - when a request is accepted (pause, resume)
 */
static void call_accepted(SalOp *op){
	LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
	LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
	SalMediaDescription *md;
	
	if (call==NULL){
		ms_warning("No call to accept.");
		return ;
	}
	/*set privacy*/
	call->current_params.privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op);

	/* 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));
	}
#ifdef BUILD_UPNP
	if (call->upnp_session != NULL) {
		linphone_core_update_upnp_from_remote_media_description(call, sal_call_get_remote_media_description(op));
	}
#endif //BUILD_UPNP

	md=sal_call_get_final_media_description(op);
	if (md) /*make sure re-invite will not propose video again*/
		call->params.has_video &= linphone_core_media_description_contains_video_stream(md);
	
	if (call->state==LinphoneCallOutgoingProgress ||
	    call->state==LinphoneCallOutgoingRinging ||
	    call->state==LinphoneCallOutgoingEarlyMedia){
		linphone_call_set_state(call,LinphoneCallConnected,"Connected");
		if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call);
	}
	if (md && !sal_media_description_empty(md) && !linphone_core_incompatible_security(lc,md)){
		linphone_call_update_remote_session_id_and_ver(call);
		if (sal_media_description_has_dir(md,SalStreamSendOnly) ||
		    sal_media_description_has_dir(md,SalStreamInactive)){
			if (lc->vtable.display_status){
				char *tmp=linphone_call_get_remote_address_as_string (call);
				char *msg=ms_strdup_printf(_("Call with %s is paused."),tmp);
				lc->vtable.display_status(lc,msg);
				ms_free(tmp);
				ms_free(msg);
			}
			linphone_core_update_streams (lc,call,md);
			linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
			if (call->refer_pending)
				linphone_core_start_refered_call(lc,call,NULL);
		}else if (sal_media_description_has_dir(md,SalStreamRecvOnly)){
			/*we are put on hold when the call is initially accepted */
			if (lc->vtable.display_status){
				char *tmp=linphone_call_get_remote_address_as_string (call);
				char *msg=ms_strdup_printf(_("Call answered by %s - on hold."),tmp);
				lc->vtable.display_status(lc,msg);
				ms_free(tmp);
				ms_free(msg);
			}
			linphone_core_update_streams (lc,call,md);
			linphone_call_set_state(call,LinphoneCallPausedByRemote,"Call paused by remote");
		}else{
			if (call->state!=LinphoneCallUpdating){
				if (call->state==LinphoneCallResuming){
					if (lc->vtable.display_status){
						lc->vtable.display_status(lc,_("Call resumed."));
					}
				}else{
					if (lc->vtable.display_status){
						char *tmp=linphone_call_get_remote_address_as_string (call);
						char *msg=ms_strdup_printf(_("Call answered by %s."),tmp);
						lc->vtable.display_status(lc,msg);
						ms_free(tmp);
						ms_free(msg);
					}
				}
			}
			linphone_core_update_streams(lc,call,md);
			/*also reflect the change if the "wished" params, in order to avoid to propose SAVP or video again
			* further in the call, for example during pause,resume, conferencing reINVITEs*/
			linphone_call_fix_call_parameters(call);
			if (!call->current_params.in_conference)
				lc->current_call=call;
			linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running");
		}
	}else{
		/*send a bye*/
		ms_error("Incompatible SDP offer received in 200Ok, need to abort the call");
		linphone_core_abort_call(lc,call,_("Incompatible, check codecs or security settings..."));
	}
}