int tsip_dialog_invite_ice_set_media_type(tsip_dialog_invite_t * self, tmedia_type_t _media_type)
{
	if(self){
		tmedia_type_t av_media_type = (_media_type & tmedia_audiovideo); // filter to keep audio and video only
		// "none" comparison is used to exclude the "first call"
		if(self->ice.media_type != tmedia_none && self->ice.media_type != av_media_type){
			// cancels contexts associated to old medias
			if(self->ice.ctx_audio && !(av_media_type & tmedia_audio)){
				tnet_ice_ctx_cancel(self->ice.ctx_audio);
			}
			if(self->ice.ctx_video && !(av_media_type & tmedia_video)){
				tnet_ice_ctx_cancel(self->ice.ctx_video);
			}
			// cancels contexts associated to new medias (e.g. session "remove" then "add")
			// cancel() on newly created contexts don't have any effect
			if(self->ice.ctx_audio && (!(av_media_type & tmedia_audio) && (self->ice.media_type & tmedia_audio))){
				//tnet_ice_ctx_cancel(self->ice.ctx_audio);
			}
			if(self->ice.ctx_video && (!(av_media_type & tmedia_video) && (self->ice.media_type & tmedia_video))){
				//tnet_ice_ctx_cancel(self->ice.ctx_video);
			}
		}
		self->ice.media_type = av_media_type;
	}
	return 0;
}
int tsip_dialog_invite_ice_process_lo(tsip_dialog_invite_t * self, const tsdp_message_t* sdp_lo)
{
	const tsdp_header_M_t* M;
	const tsdp_header_A_t *A;
	int ret = 0, i;

	if(!self || !sdp_lo){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	// cancels all ICE contexts without candidates
	// this happens if codecs negotiations mismatch for one media out of two or three
	for(i = 0; i < 2; ++i){
		struct tnet_ice_ctx_s *ctx = i == 0 ? self->ice.ctx_audio : self->ice.ctx_video;
		const char* media = i == 0 ? "audio" : "video";
		if(tnet_ice_ctx_is_active(ctx)){
			tsk_bool_t cancel = tsk_true;
			if((M = tsdp_message_find_media(sdp_lo, media))){
				if((A = tsdp_header_M_findA(M, "candidate"))){
					cancel = tsk_false;
				}
			}
			if(cancel){
				ret = tnet_ice_ctx_cancel(ctx);
			}
		}
	}

	return ret;
}
static int tsip_dialog_invite_ice_cancel_ctx(tsip_dialog_invite_t * self)
{
	int ret = 0;
	if(self){
		if((self->ice.media_type & tmedia_audio)){
			if(self->ice.ctx_audio && (ret = tnet_ice_ctx_cancel(self->ice.ctx_audio)) != 0){
				return ret;
			}
		}
		if((self->ice.media_type & tmedia_video)){
			if(self->ice.ctx_video && (ret = tnet_ice_ctx_cancel(self->ice.ctx_video)) != 0){
				return ret;
			}
		}
	}
	return 0;
}
Example #4
0
static int tsip_dialog_invite_ice_create_ctx(tsip_dialog_invite_t * self, tmedia_type_t media_type)
{
	int32_t transport_idx;
	if(!self){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	transport_idx = TSIP_DIALOG_GET_STACK(self)->network.transport_idx_default;
	if(!self->ice.ctx_audio && (media_type & tmedia_audio)){
		self->ice.ctx_audio = tnet_ice_ctx_create(self->ice.is_jingle, TNET_SOCKET_TYPE_IS_IPV6(TSIP_DIALOG_GET_STACK(self)->network.proxy_cscf_type[transport_idx]), 
					self->use_rtcp, tsk_false, tsip_dialog_invite_ice_audio_callback, self);
		if(!self->ice.ctx_audio){
			TSK_DEBUG_ERROR("Failed to create ICE audio context");
			return -2;
		}
		tnet_ice_ctx_set_stun(self->ice.ctx_audio, "stun.l.google.com", 19302, "Doubango", "*****@*****.**", "stun-password"); //FIXME
		tnet_ice_ctx_set_rtcpmux(self->ice.ctx_audio, self->use_rtcpmux);
	}
	if(!self->ice.ctx_video && (media_type & tmedia_video)){
		self->ice.ctx_video = tnet_ice_ctx_create(self->ice.is_jingle, TNET_SOCKET_TYPE_IS_IPV6(TSIP_DIALOG_GET_STACK(self)->network.proxy_cscf_type[transport_idx]), 
					self->use_rtcp, tsk_true, tsip_dialog_invite_ice_video_callback, self);
		if(!self->ice.ctx_video){
			TSK_DEBUG_ERROR("Failed to create ICE video context");
			return -2;
		}
		tnet_ice_ctx_set_stun(self->ice.ctx_video, "stun.l.google.com", 19302, "Doubango", "*****@*****.**", "stun-password"); // FIXME
		tnet_ice_ctx_set_rtcpmux(self->ice.ctx_video, self->use_rtcpmux);
	}

	// "none" comparison is used to exclude the "first call"
	if(self->ice.media_type != tmedia_none && self->ice.media_type != media_type){
		// cancels contexts associated to old medias
		if(self->ice.ctx_audio && !(media_type & tmedia_audio)){
			tnet_ice_ctx_cancel(self->ice.ctx_audio);
		}
		if(self->ice.ctx_video && !(media_type & tmedia_video)){
			tnet_ice_ctx_cancel(self->ice.ctx_video);
		}
		// cancels contexts associated to new medias (e.g. session "remove" then "add")
		// cancel() on newly created contexts don't have any effect
		if(self->ice.ctx_audio && (!(media_type & tmedia_audio) && (self->ice.media_type & tmedia_audio))){
			//tnet_ice_ctx_cancel(self->ice.ctx_audio);
		}
		if(self->ice.ctx_video && (!(media_type & tmedia_video) && (self->ice.media_type & tmedia_video))){
			//tnet_ice_ctx_cancel(self->ice.ctx_video);
		}
	}

	self->ice.media_type = media_type;
	

	// For now disable timers until both parties get candidates
	// (RECV ACK) or RECV (200 OK)
	tsip_dialog_invite_ice_timers_set(self, -1);

	// update session manager with the right ICE contexts
	if(self->msession_mgr){
		tmedia_session_mgr_set_ice_ctx(self->msession_mgr, self->ice.ctx_audio, self->ice.ctx_video);
	}

	return 0;
}