/* ============ Media Producer Interface ================= */ static int _tdav_producer_video_v4l2_set(tmedia_producer_t *p_self, const tmedia_param_t* pc_param) { int ret = 0; tdav_producer_video_v4l2_t* p_v4l2 = (tdav_producer_video_v4l2_t*)p_self; if (!p_v4l2 || !pc_param) { V4L2_DEBUG_ERROR("Invalid parameter"); return -1; } if (pc_param->value_type == tmedia_pvt_pchar) { if (tsk_striequals(pc_param->key, "local-hwnd") || tsk_striequals(pc_param->key, "preview-hwnd")) { V4L2_DEBUG_ERROR("Not implemented yet"); } else if (tsk_striequals(pc_param->key, "src-hwnd")) { V4L2_DEBUG_ERROR("Not implemented yet"); } } else if (pc_param->value_type == tmedia_pvt_int32) { if (tsk_striequals(pc_param->key, "mute")) { p_v4l2->b_muted = (TSK_TO_INT32((uint8_t*)pc_param->value) != 0); } } return ret; }
int tdav_consumer_audio_set(tdav_consumer_audio_t* self, const tmedia_param_t* param) { if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(param->plugin_type == tmedia_ppt_consumer){ if(param->value_type == tmedia_pvt_int32){ if(tsk_striequals(param->key, "gain")){ int32_t gain = *((int32_t*)param->value); if(gain<TDAV_AUDIO_GAIN_MAX && gain>=0){ TMEDIA_CONSUMER(self)->audio.gain = (uint8_t)gain; TSK_DEBUG_INFO("audio consumer gain=%u", gain); } else{ TSK_DEBUG_ERROR("%u is invalid as gain value", gain); return -2; } } else if(tsk_striequals(param->key, "volume")){ TMEDIA_CONSUMER(self)->audio.volume = TSK_TO_INT32((uint8_t*)param->value); TMEDIA_CONSUMER(self)->audio.volume = TSK_CLAMP(0, TMEDIA_CONSUMER(self)->audio.volume, 100); } } } return 0; }
/**@ingroup tsk_xml_group * Find an XML node by name * @param curr The XML node from which to start * @param name The name of the XML node to find * @param ftype The find type * @retval Returns the node which match our criteria. If none match, this method returns NULL. */ xmlNodePtr tsk_xml_find_node(const xmlNodePtr curr, const char* name, tsk_xml_node_find_type_t ftype) { xmlNodePtr node = curr; while(node) { switch(ftype) { case nft_none: return (tsk_striequals(node->name, name))? node : 0; case nft_children: node = node->children; break; case nft_parent: node = node->parent; break; case nft_next: node = node->next; break; case nft_prev: node = node->prev; break; default: return 0; } /* switch */ /* check and return value if match */ if( node && (!name || tsk_striequals(node->name, name)) ) //if( node && (name == 0 || !tsk_stricmp((const char*)node->name, name)) ) { return node; } } return 0; }
char* tdav_codec_mp4ves_sdp_att_get(const tmedia_codec_t* _self, const char* att_name) { tdav_codec_mp4ves_t *self = (tdav_codec_mp4ves_t *)_self; if(tsk_striequals(att_name, "fmtp")){ char* fmtp = tsk_null; switch(_self->bl){//FIXME: deprecated case tmedia_bl_low: default: self->profile = Simple_Profile_Level_1; break; case tmedia_bl_medium: self->profile = Simple_Profile_Level_2; break; case tmedia_bl_hight: case tmedia_bl_unrestricted: self->profile = Simple_Profile_Level_3; break; } tsk_sprintf(&fmtp, "profile-level-id=%d", self->profile); return fmtp; } else if(tsk_striequals(att_name, "imageattr")){ return tmedia_get_video_imageattr(TMEDIA_CODEC_VIDEO(self)->pref_size, TMEDIA_CODEC_VIDEO(self)->in.width, TMEDIA_CODEC_VIDEO(self)->in.height, TMEDIA_CODEC_VIDEO(self)->out.width, TMEDIA_CODEC_VIDEO(self)->out.height); } return tsk_null; }
static tsk_bool_t _fsm_cond_notify_terminated(tsip_dialog_subscribe_t* dialog, tsip_message_t* message) { const tsip_header_Subscription_State_t *hdr_state; if((hdr_state = (const tsip_header_Subscription_State_t*)tsip_message_get_header(message, tsip_htype_Subscription_State))) { return tsk_striequals(hdr_state->state, "terminated") && (hdr_state->expires < 0 || tsk_striequals(hdr_state->reason, "rejected") || tsk_striequals(hdr_state->reason, "noresource")); } return tsk_false; }
int trtp_srtp_match_line(const char* crypto_line, int32_t* tag, int32_t* crypto_type, char* key, tsk_size_t key_size) { char* v = strtok((char*)crypto_line, " :|;"); int32_t k = 0; while(v){ switch(k){ case 0: { if(tag){ *tag = atoi(v); } break; } case 1: { if(tsk_striequals(v, TRTP_SRTP_AES_CM_128_HMAC_SHA1_80)){ if(crypto_type){ *crypto_type = HMAC_SHA1_80; } } else if(tsk_striequals(v, TRTP_SRTP_AES_CM_128_HMAC_SHA1_32)){ if(crypto_type){ *crypto_type = HMAC_SHA1_32; } } else { return -0xFF; } break; } case 2: { if(!tsk_striequals(v, "inline")){ return -0xFF; } break; } case 3: { if(key && key_size){ memset(key, 0, key_size); memcpy(key, v, TSK_MIN(key_size, tsk_strlen(v))); } return 0; } } ++k; v = strtok(tsk_null, " :|;"); } return -0xF0; }
static int tdav_codec_mp4ves_set(tmedia_codec_t* self, const tmedia_param_t* param) { tdav_codec_mp4ves_t* mp4ves = (tdav_codec_mp4ves_t*)self; if(!self->opened){ TSK_DEBUG_ERROR("Codec not opened"); return -1; } if(param->value_type == tmedia_pvt_int32){ if(tsk_striequals(param->key, "action")){ tmedia_codec_action_t action = (tmedia_codec_action_t)TSK_TO_INT32((uint8_t*)param->value); switch(action){ case tmedia_codec_action_encode_idr: { mp4ves->encoder.force_idr = tsk_true; break; } case tmedia_codec_action_bw_down: { mp4ves->encoder.quality = TSK_CLAMP(1, (mp4ves->encoder.quality + 1), 31); mp4ves->encoder.context->global_quality = FF_QP2LAMBDA * mp4ves->encoder.quality; break; } case tmedia_codec_action_bw_up: { mp4ves->encoder.quality = TSK_CLAMP(1, (mp4ves->encoder.quality - 1), 31); mp4ves->encoder.context->global_quality = FF_QP2LAMBDA * mp4ves->encoder.quality; break; } } } else if(tsk_striequals(param->key, "rotation")){ int rotation = *((int32_t*)param->value); if(mp4ves->encoder.rotation != rotation){ if(self->opened){ int ret; mp4ves->encoder.rotation = rotation; if((ret = tdav_codec_mp4ves_close_encoder(mp4ves))){ return ret; } if((ret = tdav_codec_mp4ves_open_encoder(mp4ves))){ return ret; } } } return 0; } } return -1; }
static int init_neg_types(tdav_session_msrp_t* msrp, const tsdp_header_M_t* m) { const tsdp_header_A_t* A; if((A = tsdp_header_M_findA(m, "accept-types"))){ char* atype = strtok((char*)A->value, " "); const char* default_atype = atype; while(atype){ if(tsk_striequals(atype, "message/CPIM")){ tsk_strupdate(&msrp->neg_accept_type, atype); if((A = tsdp_header_M_findA(m, "accept-wrapped-types"))){ char* awtype = strtok((char*)A->value, " "); tsk_strupdate(&msrp->neg_accept_w_type, awtype); // first } break; } atype = strtok(tsk_null, " "); } if(!msrp->neg_accept_type){ tsk_strupdate(&msrp->neg_accept_type, default_atype); } return 0; } return -1; }
char* tdav_codec_dtmf_sdp_att_get(const tmedia_codec_t* self, const char* att_name) { if(tsk_striequals(att_name, "fmtp")){ return tsk_strdup("0-16"); } return tsk_null; }
/* ============ Media Consumer Interface ================= */ int tdav_consumer_audiounit_set(tmedia_consumer_t* self, const tmedia_param_t* param) { tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self; if (param->plugin_type == tmedia_ppt_consumer) { if (param->value_type == tmedia_pvt_int32) { if (tsk_striequals(param->key, "interrupt")) { int32_t interrupt = *((uint8_t*)param->value) ? 1 : 0; return tdav_audiounit_handle_interrupt(consumer->audioUnitHandle, interrupt); } else if (tsk_striequals(param->key, "pause") || tsk_striequals(param->key, "hold")) { int32_t pause = *((uint8_t*)param->value) ? 1 : 0; return pause ? tdav_consumer_audiounit_pause(self) : tdav_consumer_audiounit_resume(self); } } } return tdav_consumer_audio_set(TDAV_CONSUMER_AUDIO(self), param); }
/* ============ Media Producer Interface ================= */ int tdav_producer_audiounit_set(tmedia_producer_t* self, const tmedia_param_t* param) { tdav_producer_audiounit_t* producer = (tdav_producer_audiounit_t*)self; if(param->plugin_type == tmedia_ppt_producer){ if(param->value_type == tmedia_pvt_int32){ if (tsk_striequals(param->key, "mute")) { producer->muted = TSK_TO_INT32((uint8_t*)param->value); return tdav_audiounit_handle_mute(((tdav_producer_audiounit_t*)self)->audioUnitHandle, producer->muted); } else if (tsk_striequals(param->key, "interrupt")) { int32_t interrupt = *((uint8_t*)param->value) ? 1 : 0; return tdav_audiounit_handle_interrupt(producer->audioUnitHandle, interrupt); } } } return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param); }
tsk_bool_t tdav_codec_mp4ves_sdp_att_match(const tmedia_codec_t* _self, const char* att_name, const char* att_value) { tdav_codec_mp4ves_t *self = (tdav_codec_mp4ves_t *)_self; if(!self){ TSK_DEBUG_ERROR("Invalid parameter"); return tsk_false; } if(tsk_striequals(att_name, "fmtp")){ tsk_params_L_t* params ; /* e.g. profile-level-id=1; xx=yy */ if((params = tsk_params_fromstring(att_value, ";", tsk_true))){ int val_int; if((val_int = tsk_params_get_param_value_as_int(params, "profile-level-id")) != -1){ TSK_DEBUG_INFO("Proposed profile-level-id=%d", val_int); self->profile = val_int; // FIXME: Take the remote profile-level-id even if the bandwidth level doesn't match } TSK_OBJECT_SAFE_FREE(params); } switch (self->profile ) { case Simple_Profile_Level_1: TMEDIA_CODEC_VIDEO(self)->out.width = TMEDIA_CODEC_VIDEO(self)->in.width = 176; TMEDIA_CODEC_VIDEO(self)->in.height = TMEDIA_CODEC_VIDEO(self)->out.height = 144; break; case Simple_Profile_Level_2: case Simple_Profile_Level_3: default: TMEDIA_CODEC_VIDEO(self)->out.width = TMEDIA_CODEC_VIDEO(self)->in.width = 352; TMEDIA_CODEC_VIDEO(self)->in.height = TMEDIA_CODEC_VIDEO(self)->out.height = 288; break; } } else if(tsk_striequals(att_name, "imageattr")){ unsigned in_width, in_height, out_width, out_height; if(tmedia_parse_video_imageattr(att_value, TMEDIA_CODEC_VIDEO(self)->pref_size, &in_width, &in_height, &out_width, &out_height) != 0){ return tsk_false; } TMEDIA_CODEC_VIDEO(self)->in.width = in_width; TMEDIA_CODEC_VIDEO(self)->in.height = in_height; TMEDIA_CODEC_VIDEO(self)->out.width = out_width; TMEDIA_CODEC_VIDEO(self)->out.height = out_height; } return tsk_true; }
static char* tdav_codec_ilbc_sdp_att_get(const tmedia_codec_t* codec, const char* att_name) { if(tsk_striequals(att_name, "fmtp")){ char* fmtp = tsk_null; tsk_sprintf(&fmtp, "mode=%d", TDAV_ILBC_MODE); return fmtp; } return tsk_null; }
/**@ingroup tsk_xml_group * Get an XML namespace from an XML document * @param docPtr A pointer to the XML document * @param node The XML node from which to extract the namespace * @param href The namespace href * @retval The Namespace value matching our criteria (href) */ xmlNsPtr tsk_xml_get_namespace(xmlDocPtr docPtr, xmlNodePtr node, const char *href) { xmlNs *ns = *xmlGetNsList(docPtr, node); while (ns) { if (tsk_striequals(ns->href, href)) return ns; else ns = ns->next; } return 0; }
int tdav_session_msrp_send_message(tmedia_session_msrp_t* self, const void* data, tsk_size_t size, const tmedia_params_L_t *params) { const tdav_session_msrp_t* msrp; const tmedia_param_t* param; int ret; const tsk_list_item_t* item; const char* content_type = tsk_null; const char* w_content_type = tsk_null; if(!data || !size || !(msrp = (tdav_session_msrp_t*)self) || !msrp->sender){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } tsk_list_foreach(item, params){ if((param = TMEDIA_PARAM(item->data))){ if((param->media_type & tmedia_msrp) == param->media_type && param->plugin_type == tmedia_ppt_session && param->value_type == tmedia_pvt_pchar){ if(tsk_striequals(param->key, "content-type")){ content_type = (const char*)param->value; } else if(tsk_striequals(param->key, "w-content-type")){ w_content_type = (const char*)param->value; } } } } if(content_type || w_content_type){ // user-defined content-types ret = tsmrp_sender_send_data(msrp->sender, data, size, content_type, w_content_type); } else{ // neg. content-types ret = tsmrp_sender_send_data(msrp->sender, data, size, msrp->neg_accept_type, msrp->neg_accept_w_type ); } return ret; }
/* ============ Media Producer Interface ================= */ int tdav_producer_audiounit_set(tmedia_producer_t* self, const tmedia_param_t* param) { if(param->plugin_type == tmedia_ppt_producer){ if(param->value_type == tmedia_pvt_int32){ if(tsk_striequals(param->key, "mute")){ int32_t mute = TSK_TO_INT32((uint8_t*)param->value); return tdav_audiounit_handle_mute(((tdav_producer_audiounit_t*)self)->audioUnitHandle, mute ? tsk_true : tsk_false); } } } return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param); }
tnet_dtls_setup_t tnet_dtls_get_setup_from_string(const char* setup) { if (setup){ int32_t i; for (i = 0; i < TNET_DTLS_SETUP_MAX; ++i){ if (tsk_striequals(TNET_DTLS_SETUP_NAMES[i], setup)){ return (tnet_dtls_setup_t)i; } } } return tnet_dtls_setup_none; }
tnet_dtls_hash_type_t tnet_dtls_get_hash_from_string(const char* hash) { if (hash){ int32_t i; for (i = 0; i < TNET_DTLS_HASH_TYPE_MAX; ++i){ if (tsk_striequals(TNET_DTLS_HASH_NAMES[i], hash)){ return (tnet_dtls_hash_type_t)i; } } } return tnet_dtls_hash_type_none; }
//#define tdav_producer_audioqueue_set tsk_null int tdav_producer_audioqueue_set(tmedia_producer_t* self, const tmedia_param_t* param) { tdav_producer_audioqueue_t* producer = (tdav_producer_audioqueue_t*)self; if(param->plugin_type == tmedia_ppt_producer){ if(param->value_type == tmedia_pvt_int32){ if(tsk_striequals(param->key, "mute")){ producer->muted = TSK_TO_INT32((uint8_t*)param->value); return 1; } } } return tdav_producer_audio_set(TDAV_PRODUCER_AUDIO(self), param); }
/**@ingroup thttp_auth_group * * Generates HTTP digest response as per RFC 2617 subclause 3.2.2.1. * * @param [in,out] ha1 HA1 string generated using @ref thttp_auth_digest_HA1 or @ref thttp_auth_digest_HA1sess. * @param [in,out] nonce The nonce value. * @param [in,out] noncecount The nonce count. * @param [in,out] cnonce The client nounce (unquoted). * @param [in,out] qop The Quality Of Protection (unquoted). * @param [in,out] ha2 HA2 string generated using @ref thttp_auth_digest_HA2. * @param [in,out] response A pointer to the response. * * @return Zero if succeed and non-zero error code otherwise. **/ int thttp_auth_digest_response(const tsk_md5string_t *ha1, const char* nonce, const nonce_count_t noncecount, const char* cnonce, const char* qop, const tsk_md5string_t* ha2, tsk_md5string_t* response) { int ret; /* RFC 2617 3.2.2.1 Request-Digest ============ CASE 1 ============ If the "qop" value is "auth" or "auth-int": request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" nc-value ":" unq(cnonce-value) ":" unq(qop-value) ":" H(A2) ) <"> ============ CASE 2 ============ If the "qop" directive is not present (this construction is for compatibility with RFC 2069): request-digest = <"> < KD ( H(A1), unq(nonce-value) ":" H(A2) ) > <"> */ char *res = tsk_null; if (tsk_striequals(qop, "auth") || tsk_striequals(qop, "auth-int")){ /* CASE 1 */ tsk_sprintf(&res, "%s:%s:%s:%s:%s:%s", *ha1, nonce, noncecount, cnonce, qop, *ha2); } else{ /* CASE 2 */ tsk_sprintf(&res, "%s:%s:%s", *ha1, nonce, *ha2); } ret = tsk_md5compute(res, tsk_strlen(res), response); TSK_FREE(res); return ret; }
/**@ingroup thttp_auth_group * Generates digest HA2 value as per RFC 2617 subclause 3.2.2.3. * * * @param [in,out] method The HTTP/SIP method name. * @param [in,out] url The HTTP URL or SIP URI of the request. * @param [in,out] entity_body The entity body. * @param [in,out] qop The Quality Of Protection. * @param [in,out] ha2 A pointer to the response. * * @return Zero if succeed and non-zero error code otherwise. **/ int thttp_auth_digest_HA2(const char* method, const char* url, const tsk_buffer_t* entity_body, const char* qop, tsk_md5string_t* ha2) { int ret; /* RFC 2617 - 3.2.2.3 A2 If the "qop" directive's value is "auth" or is unspecified, then A2 is: A2 = Method ":" digest-url-value If the "qop" value is "auth-int", then A2 is: A2 = Method ":" digest-url-value ":" H(entity-body) */ char *a2 = tsk_null; if (!qop || tsk_strempty(qop) || tsk_striequals(qop, "auth")){ tsk_sprintf(&a2, "%s:%s", method, url); } else if (tsk_striequals(qop, "auth-int")) { if (entity_body && entity_body->data){ tsk_md5string_t hEntity; if ((ret = tsk_md5compute(entity_body->data, entity_body->size, &hEntity))){ goto bail; } tsk_sprintf(&a2, "%s:%s:%s", method, url, hEntity); } else{ tsk_sprintf(&a2, "%s:%s:%s", method, url, TSK_MD5_EMPTY); } } ret = tsk_md5compute(a2, tsk_strlen(a2), ha2); bail: TSK_FREE(a2); return ret; }
static char* tdav_codec_g729ab_sdp_att_get(const tmedia_codec_t* codec, const char* att_name) { tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)codec; if(tsk_striequals(att_name, "fmtp")){ if(g729a->encoder.vad_enable){ return tsk_strdup("annexb=yes"); } else{ return tsk_strdup("annexb=no"); } } return tsk_null; }
/* ======================== conds ======================== */ static tsk_bool_t _fsm_cond_get_local_candidates(tsip_dialog_invite_t* self, tsip_message_t* message) { if(self->supported.ice){ tsk_bool_t use_ice = tsk_false; // "action->media.type" will be defined for locally initiated media update tmedia_type_t new_media = TSIP_DIALOG(self)->curr_action ? TSIP_DIALOG(self)->curr_action->media.type : tmedia_none; if(message && TSIP_MESSAGE_HAS_CONTENT(message) && tsk_striequals("application/sdp", TSIP_MESSAGE_CONTENT_TYPE(message))){ // If this code is called this means that we are the "answerer" // only gets the candidates if ICE is enabled and the remote peer supports ICE tsdp_message_t* sdp_ro; const tsdp_header_M_t* M; int index; if(!(sdp_ro = tsdp_message_parse(TSIP_MESSAGE_CONTENT_DATA(message), TSIP_MESSAGE_CONTENT_DATA_LENGTH(message)))){ TSK_DEBUG_ERROR("Failed to parse remote sdp message"); return tsk_false; } index = 0; while((M = (const tsdp_header_M_t*)tsdp_message_get_headerAt(sdp_ro, tsdp_htype_M, index++))){ if(!tsdp_header_M_findA(M, "candidate")){ use_ice = tsk_false; // do not use ICE if at least on media is ICE-less (e.g. MSRP) break; } use_ice = tsk_true; // only use ICE if there is a least one media line } new_media = tmedia_type_from_sdp(sdp_ro); TSK_OBJECT_SAFE_FREE(sdp_ro); } else if(!message){ // we are the "offerer" -> use ICE only for audio or video medias (ignore ice for MSRP) use_ice = (new_media & tmedia_audio) || (new_media & tmedia_video); } if(use_ice){ if(!self->ice.ctx_audio && !self->ice.ctx_video){ // First time return tsk_true; } else{ if(self->ice.media_type != new_media){ return tsk_true; } return !tsip_dialog_invite_ice_got_local_candidates(self); } } } return tsk_false; }
static char* tdav_codec_h264_sdp_att_get(const tmedia_codec_t* self, const char* att_name) { char* att = tdav_codec_h264_common_sdp_att_get((const tdav_codec_h264_common_t*)self, att_name); if(att && tsk_striequals(att_name, "fmtp")) { tsk_strcat_2(&att, "; impl=%s", #if HAVE_FFMPEG "FFMPEG" #elif HAVE_H264_PASSTHROUGH "PASSTHROUGH" #endif ); } return att; }
static tsk_bool_t tdav_codec_g729ab_sdp_att_match(const tmedia_codec_t* codec, const char* att_name, const char* att_value) { tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)codec; if(tsk_striequals(att_name, "fmtp")){ tsk_params_L_t* params = tsk_null; const char* val_str; if((params = tsk_params_fromstring(att_value, ";", tsk_true))){ if((val_str = tsk_params_get_param_value(params, "annexb"))){ g729a->encoder.vad_enable &= tsk_strequals(val_str, "yes") ? 1 : 0; } TSK_OBJECT_SAFE_FREE(params); } } return tsk_true; }
// Current -> (iINVITE) -> Current static int x0500_Current_2_Current_X_iINVITE(va_list *app) { int ret; tsip_dialog_invite_t *self; const tsip_action_t* action; const tsip_message_t *message; self = va_arg(*app, tsip_dialog_invite_t *); message = va_arg(*app, const tsip_message_t *); action = va_arg(*app, const tsip_action_t *); self->is_client = tsk_false; ret = tsip_dialog_invite_ice_save_action(self, _fsm_action_iINVITE, action, message); // Cancel without notifying ("silent mode") and perform the operation right now ("sync mode") tsip_dialog_invite_ice_cancel_silent_and_sync_ctx(self); // set remote candidates if(TSIP_MESSAGE_HAS_CONTENT(message)){ if(tsk_striequals("application/sdp", TSIP_MESSAGE_CONTENT_TYPE(message))){ tsdp_message_t* sdp_ro; if(!(sdp_ro = tsdp_message_parse(TSIP_MESSAGE_CONTENT_DATA(message), TSIP_MESSAGE_CONTENT_DATA_LENGTH(message)))){ TSK_DEBUG_ERROR("Failed to parse remote sdp message"); return -2; } // create ICE context if((ret = tsip_dialog_invite_ice_create_ctx(self, tmedia_type_from_sdp(sdp_ro)))){ TSK_DEBUG_ERROR("tsip_dialog_invite_ice_create_ctx() failed"); return ret; } ret = tsip_dialog_invite_ice_process_ro(self, sdp_ro, tsk_true); TSK_OBJECT_SAFE_FREE(sdp_ro); } else{ TSK_DEBUG_ERROR("[%s] content-type is not supportted", TSIP_MESSAGE_CONTENT_TYPE(message)); return -3; } } // For now disable ICE timers until we send the 2xx and receive the ACK ret = tsip_dialog_invite_ice_timers_set(self, -1); // Start ICE ret = tsip_dialog_invite_ice_start_ctx(self); return ret; }
static int tdav_speex_denoise_set(tmedia_denoise_t* _self, const tmedia_param_t* param) { tdav_speex_denoise_t *self = (tdav_speex_denoise_t *)_self; if(!self || !param){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(param->value_type == tmedia_pvt_int32){ if(tsk_striequals(param->key, "echo-tail")){ int32_t echo_tail = *((int32_t*)param->value); TSK_DEBUG_INFO("speex_set_echo_tail(%d) ignore", echo_tail); // because Speex AEC just do not work (use WebRTC) return 0; } } return -1; }
/**@ingroup txc_document_group * Create a custom XCAP document selector URI as per <a href="http://tools.ietf.org/html/rfc4825#section-6.2">RFC 4825 subclause 6.2</a> * @param xcaproot The XCAP Root URI. A context that contains all the documents across all * application usages and users that are managed by the server. For more information see <a href="http://tools.ietf.org/html/rfc4825#section-4">RFC 4825 subclause 4</a> * @param auid The Application Unique ID. unique identifier within the namespace of application unique IDs created by this specification * that differentiates XCAP resources accessed by one application from XCAP resources accessed by another. * For more information see <a href="http://tools.ietf.org/html/rfc4825#section-4">RFC 4825 subclause 4</a> * @param xui The XCAP User Identifier. The XUI is a string, valid as a path element in an HTTP URI, that is associated with each user served * by the XCAP server. For more information see <a href="http://tools.ietf.org/html/rfc4825#section-4">RFC 4825 subclause 4</a>. * For global document, this parameter must be NULL or equal to "global" * @param name The document name. * @retval The HTTP URI containing the XCAP root and document selector, resulting in the selection of a specific document. As a result, performing a GET against the document URI would retrieve the document. * If supplied parameters are not valide this method will return NULL. * You must free the returned string using TSK_FREE or TSK_SAFE_FREE. * @sa @ref TXC_DOC_GET_SEL and @ref TXC_DOC_GET_SEL2 */ char* txc_doc_get_cust_sel(const char *xcaproot, const char *auid, const char *xui, const char *name) { char *selector = 0; if(!xcaproot || !auid || !name) return 0; if(!xui || tsk_striequals("global", xui)) { /* xdm-root/auid-name/global/doc-name */ tsk_sprintf(&selector, "%s/%s/global/%s", xcaproot, auid, name); } else { /* xdm-root/auid-name/users/xui/doc-name */ tsk_sprintf(&selector, "%s/%s/users/%s/%s", xcaproot, auid, xui, name); } return selector; }
/**@ingroup tmedia_codec_group * Creates a new codec using an already registered plugin. * @param format The format of the codec to create (e.g. "0" for PCMU or "8" for PCMA or "*" for MSRP) * @sa @ref tmedia_codec_plugin_register() */ tmedia_codec_t* tmedia_codec_create(const char* format) { tmedia_codec_t* codec = tsk_null; const tmedia_codec_plugin_def_t* plugin; tsk_size_t i = 0; while((i < TMED_CODEC_MAX_PLUGINS) && (plugin = __tmedia_codec_plugins[i++])) { if(plugin->objdef && tsk_striequals(plugin->format, format)) { if((codec = tsk_object_new(plugin->objdef))) { /* initialize the newly created codec */ codec->id = plugin->codec_id; codec->dyn = plugin->dyn; codec->plugin = plugin; codec->bl = tmedia_bl_medium; switch(plugin->type) { case tmedia_audio: { /* Audio codec */ tmedia_codec_audio_t* audio = TMEDIA_CODEC_AUDIO(codec); tmedia_codec_audio_init(TMEDIA_CODEC(audio), plugin->name, plugin->desc, plugin->format); break; } case tmedia_video: { /* Video codec */ tmedia_codec_video_t* video = TMEDIA_CODEC_VIDEO(codec); tmedia_codec_video_init(TMEDIA_CODEC(video), plugin->name, plugin->desc, plugin->format); break; } case tmedia_msrp: { /* Msrp codec */ tmedia_codec_msrp_init(codec, plugin->name, plugin->desc); break; } default: { /* Any other codec */ tmedia_codec_init(codec, plugin->type, plugin->name, plugin->desc, plugin->format); break; } } break; } } } return codec; }
static int tdav_webrtc_denoise_set(tmedia_denoise_t* _self, const tmedia_param_t* param) { tdav_webrtc_denoise_t *self = (tdav_webrtc_denoise_t *)_self; if(!self || !param){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(param->value_type == tmedia_pvt_int32){ if(tsk_striequals(param->key, "echo-tail")){ int32_t echo_tail = *((int32_t*)param->value); self->echo_tail = TSK_CLAMP(WEBRTC_MIN_ECHO_TAIL, echo_tail, WEBRTC_MAX_ECHO_TAIL); TSK_DEBUG_INFO("set_echo_tail (%d->%d)", echo_tail, self->echo_tail); return 0; } } return -1; }