static tsk_object_t* tnet_ice_event_dtor(tsk_object_t * self) { tnet_ice_event_t *e = self; if(e){ TSK_SAFE_FREE(e->phrase); TSK_OBJECT_SAFE_FREE(e->action); e->ctx = tsk_null; // not the owner (const) } return self; }
static tsk_object_t* tdav_video_jb_dtor(tsk_object_t * self) { tdav_video_jb_t *jb = self; if(jb){ if(jb->started){ tdav_video_jb_stop(jb); } TSK_OBJECT_SAFE_FREE(jb->frames); if(jb->decode_thread_cond){ tsk_condwait_destroy(&jb->decode_thread_cond); } TSK_SAFE_FREE(jb->buffer.ptr); tsk_safeobj_deinit(jb); } return self; }
static tsk_object_t* tnet_ice_candidate_dtor(tsk_object_t * self) { tnet_ice_candidate_t *candidate = self; if(candidate){ TSK_SAFE_FREE(candidate->transport_str); TSK_SAFE_FREE(candidate->cand_type_str); TSK_OBJECT_SAFE_FREE(candidate->extension_att_list); TSK_OBJECT_SAFE_FREE(candidate->socket); TSK_SAFE_FREE(candidate->stun.nonce); TSK_SAFE_FREE(candidate->stun.realm); TSK_SAFE_FREE(candidate->stun.srflx_addr); TSK_SAFE_FREE(candidate->ufrag); TSK_SAFE_FREE(candidate->pwd); TSK_SAFE_FREE(candidate->tostring); } return self; }
int tsip_dialog_invite_ice_process_ro(tsip_dialog_invite_t * self, const tsdp_message_t* sdp_ro, tsk_bool_t is_remote_offer) { char* ice_remote_candidates; const tsdp_header_M_t* M; tsk_size_t index; const tsdp_header_A_t *A; const tsdp_header_O_t *O; const char* sess_ufrag = tsk_null; const char* sess_pwd = tsk_null; int ret = 0, i; struct tnet_ice_ctx_s *ctx; if(!self || !sdp_ro){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(!self->ice.ctx_audio && !self->ice.ctx_video){ return 0; } // make sure this is different SDP if((O = (const tsdp_header_O_t*)tsdp_message_get_header(sdp_ro, tsdp_htype_O))){ if(self->ice.last_sdp_ro_ver == (int32_t)O->sess_version){ TSK_DEBUG_INFO("ICE: ignore processing SDP RO because version haven't changed"); return 0; } self->ice.last_sdp_ro_ver = (int32_t)O->sess_version; } // session level attributes if((A = tsdp_message_get_headerA(sdp_ro, "ice-ufrag"))){ sess_ufrag = A->value; } if((A = tsdp_message_get_headerA(sdp_ro, "ice-pwd"))){ sess_pwd = A->value; } #if 0 // Use RTCWeb Profile (tmedia_profile_rtcweb) { const tsdp_header_S_t *S; if((S = (const tsdp_header_S_t *)tsdp_message_get_header(sdp_ro, tsdp_htype_S)) && S->value){ self->ice.is_jingle = tsk_strcontains(S->value, tsk_strlen(S->value), "webrtc"); } } #endif for(i = 0; i < 2; ++i){ if((M = tsdp_message_find_media(sdp_ro, i==0 ? "audio": "video"))){ const char *ufrag = sess_ufrag, *pwd = sess_pwd; tsk_bool_t remote_use_rtcpmux = (tsdp_header_M_findA(M, "rtcp-mux") != tsk_null); ctx = (i==0 ? self->ice.ctx_audio : self->ice.ctx_video); ice_remote_candidates = tsk_null; index = 0; if((A = tsdp_header_M_findA(M, "ice-ufrag"))){ ufrag = A->value; } if((A = tsdp_header_M_findA(M, "ice-pwd"))){ pwd = A->value; } while((A = tsdp_header_M_findA_at(M, "candidate", index++))){ tsk_strcat_2(&ice_remote_candidates, "%s\r\n", A->value); } // ICE processing will be automatically stopped if the remote candidates are not valid // ICE-CONTROLLING role if we are the offerer ret = tnet_ice_ctx_set_remote_candidates(ctx, ice_remote_candidates, ufrag, pwd, !is_remote_offer, self->ice.is_jingle); TSK_SAFE_FREE(ice_remote_candidates); // Now that 'rtcp-mux' option have been updated by the session pass the value to the ICE ctx ret = tnet_ice_ctx_set_rtcpmux(ctx, (self->use_rtcpmux && remote_use_rtcpmux)); } } return ret; }