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; }
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; }