static int _tnet_ice_candidate_tostring( uint8_t* foundation, uint32_t comp_id, const char* transport_str, uint32_t priority, const char* connection_addr, tnet_port_t port, const char* cand_type_str, const tsk_params_L_t *extension_att_list, char** output) { if(!output){ TSK_DEBUG_ERROR("Invalid argument"); return -1; } tsk_sprintf(output, "%s %d %s %d %s %d typ %s", foundation, comp_id, transport_str, priority, connection_addr, port, cand_type_str); if(extension_att_list){ const tsk_list_item_t *item; tsk_list_foreach(item, extension_att_list){ tsk_strcat_2(output, " %s %s", TSK_PARAM(item->data)->name, TSK_PARAM(item->data)->value); } }
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; }
/** Internal function */ char* __txcap_selector_get_url_2(const char* xcap_root, const char* auid_id, const char* xui, const char* doc_name, va_list* app) { char* ret = tsk_null; char* node = tsk_null; if(!xcap_root && !auid_id){ goto bail; } /* ==document== */ if(!(ret = txcap_selector_get_document_2(xcap_root, auid_id, xui, doc_name))){ TSK_DEBUG_ERROR("Failed to compute XCAP document URL."); goto bail; } /* ==node== */ if((node = txcap_selector_get_node_2(auid_id, app))){ /* append node root */ char* temp = tsk_null; tsk_sprintf(&temp, "/~~/%s", auid_id); tsk_strcat(&ret, temp); /* append node */ tsk_strcat(&ret, node); /* free */ TSK_FREE(temp); TSK_FREE(node); } bail: return ret; }
/**@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 tsk_string_group * Adds quotes to the beginning and end of @a str. * @param str The string to quote. * @param lquote Quote to add to the begining of @a str. * @param rquote Quote to add to the end of @a str. */ void tsk_strquote_2(char **str, char lquote, char rquote) { if(str && *str){ char *result = tsk_null; tsk_sprintf(&result, "%c%s%c", lquote, *str, rquote); tsk_free((void**)str); *str = result; } }
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 tmedia_codec_group * Gets the rtpmap attribute associated to this code. * @param self the codec for which to get the rtpmap attribute. Should be created using @ref tmedia_codec_create(). * @retval rtpmap string (e.g. "AMR-WB/16000/2" or "H261/90000") if succeed and Null otherwise. It's up to the caller to free the * returned string. */ char* tmedia_codec_get_rtpmap(const tmedia_codec_t* self) { char* rtpmap = tsk_null; if(!self || !self->plugin) { TSK_DEBUG_ERROR("invalid parameter"); return tsk_null; } if(self->type & tmedia_video) { /* const tmedia_codec_video_t* videoCodec = (const tmedia_codec_video_t*)self; */ tsk_sprintf(&rtpmap, "%s %s", self->neg_format? self->neg_format : self->format, self->name); if(self->plugin->rate) { tsk_strcat_2(&rtpmap, "/%d", self->plugin->rate); } } else if(self->type & tmedia_audio) { /* const tmedia_codec_audio_t* audioCodec = (const tmedia_codec_audio_t*)self; */ // special case for G.722 which has fake rate if(tsk_strequals(self->plugin->format,TMEDIA_CODEC_FORMAT_G722)) { tsk_sprintf(&rtpmap, "%s %s/8000/%d", self->neg_format? self->neg_format : self->format, self->name, self->plugin->audio.channels); } else { tsk_sprintf(&rtpmap, "%s %s", self->neg_format? self->neg_format : self->format, self->name); if(self->plugin->rate) { tsk_strcat_2(&rtpmap, "/%d", self->plugin->rate); } if(self->plugin->audio.channels > 0) { tsk_strcat_2(&rtpmap, "/%d", self->plugin->audio.channels); } } } else if(self->type & tmedia_t140) { tsk_sprintf(&rtpmap, "%s %s", self->neg_format? self->neg_format : self->format, self->name); if(self->plugin->rate) { tsk_strcat_2(&rtpmap, "/%d", self->plugin->rate); } } else { } return rtpmap; }
/**@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; }
/**@ingroup thttp_auth_group * Generates digest HA1 value as per RFC 2617 subclause 3.2.2.2. * * * @param [in,out] username The user's name (unquoted) in the specified @a realm. * @param [in,out] realm The realm. (unquoted) * @param [in,out] password The user's password. * @param [in,out] ha1 A pointer to the result. * * @return Zero if succeed and non-zero error code otherwise. **/ int thttp_auth_digest_HA1(const char* username, const char* realm, const char* password, tsk_md5string_t* ha1) { int ret; /* RFC 2617 - 3.2.2.2 A1 A1 = unq(username-value) ":" unq(realm-value) ":" passwd */ char *a1 = tsk_null; tsk_sprintf(&a1, "%s:%s:%s", username, realm, password); ret = tsk_md5compute(a1, tsk_strlen(a1), ha1); TSK_FREE(a1); return ret; }
/**@ingroup thttp_auth_group * * Generates digest HA1 value for 'MD5-sess' algo as per RFC 2617 subclause 3.2.2.2. * * * @param [in,out] username The user's name (unquoted) in the specified @a realm. * @param [in,out] realm The realm (unquoted). * @param [in,out] password The user's password. * @param [in,out] nonce The nonce (unquoted). * @param [in,out] cnonce The client nonce (unquoted). * @param [in,out] ha1sess A pointer to the result. * * @return Zero if succeed and non-zero error code otherwise. **/ int thttp_auth_digest_HA1sess(const char* username, const char* realm, const char* password, const char* nonce, const char* cnonce, tsk_md5string_t* ha1sess) { int ret; /* RFC 2617 - 3.2.2.2 A1 A1 = H( unq(username-value) ":" unq(realm-value) ":" passwd ) ":" unq(nonce-value) ":" unq(cnonce-value) */ char *a1sess = tsk_null; tsk_sprintf(&a1sess, "%s:%s:%s:%s:%s", username, realm, password, nonce, cnonce); ret = tsk_md5compute(a1sess, tsk_strlen(a1sess), ha1sess); TSK_FREE(a1sess); return ret; }
thttp_header_t *thttp_challenge_create_header_authorization(thttp_challenge_t *self, const char* username, const char* password, const thttp_request_t *request) { char *uristring = tsk_null; thttp_header_t *header = tsk_null; if (!self || !request || !request->line.request.url) { TSK_DEBUG_ERROR("Invalid parameter"); goto bail; } /* Sets URI: hpath do not start with / ==> append a '/'*/ tsk_sprintf(&uristring, "/%s", request->line.request.url->hpath ? request->line.request.url->hpath : ""); header = thttp_challenge_create_header_authorization_2(self, username, password, request->line.request.method, uristring, request->Content); bail: TSK_FREE(uristring); return header; }
/**@ingroup thttp_auth_group * * Generates HTTP-basic response as per RFC 2617. * * @param [in,out] userid The user-id. * @param [in,out] password The user-password. * @param [in,out] response A pointer to the response. It will be up to the caller to free the newly allocated buffer. * * @return The size of the response. **/ tsk_size_t thttp_auth_basic_response(const char* userid, const char* password, char** response) { tsk_size_t ret; /* RFC 2617 - 2 Basic Authentication Scheme To receive authorization, the client sends the userid and password, separated by a single colon (":") character, within a base64 [7] encoded string in the credentials. */ char *res = 0; tsk_sprintf(&res, "%s:%s", userid, password); ret = tsk_base64_encode((const uint8_t*)res, tsk_strlen(res), response); TSK_FREE(res); return ret; }
static char* tdav_codec_opus_sdp_att_get(const tmedia_codec_t* codec, const char* att_name) { tdav_codec_opus_t* opus = (tdav_codec_opus_t*)codec; if(!opus) { TSK_DEBUG_ERROR("Invalid parameter"); return tsk_null; } if(tsk_striequals(att_name, "fmtp")) { char* fmtp = tsk_null; tsk_sprintf(&fmtp, "maxplaybackrate=%d; sprop-maxcapturerate=%d; stereo=%d; sprop-stereo=%d; useinbandfec=%d; usedtx=%d", TMEDIA_CODEC(opus)->in.rate, TMEDIA_CODEC(opus)->out.rate, (TMEDIA_CODEC_AUDIO(opus)->in.channels == 2) ? 1 : 0, (TMEDIA_CODEC_AUDIO(opus)->out.channels == 2) ? 1 : 0, opus->decoder.fec_enabled ? 1 : 0, opus->decoder.dtx_enabled ? 1 : 0 ); return fmtp; } return tsk_null; }
thttp_header_t *thttp_challenge_create_header_authorization(thttp_challenge_t *self, const char* username, const char* password, const thttp_request_t *request) { char* response = tsk_null; tsk_size_t response_size = 0; nonce_count_t nc; char *uristring = tsk_null; thttp_header_t *header = 0; if (!self || !request || !request->line.request.url){ goto bail; } /* Sets URI: hpath do not start with / ==> append a '/'*/ tsk_sprintf(&uristring, "/%s", request->line.request.url->hpath ? request->line.request.url->hpath : ""); /* We compute the nc here because @ref thttp_challenge_get_response function will increment it's value. */ if (self->nc){ THTTP_NCOUNT_2_STRING(self->nc, nc); } /* Computes the response (Basic and Digest)*/ if (THTTP_CHALLENGE_IS_DIGEST(self)){ if (thttp_challenge_get_digest_response(self, username, password, request->line.request.method, uristring, request->Content, &response)){ goto bail; } response_size = (TSK_MD5_DIGEST_SIZE * 2); } else if (THTTP_CHALLENGE_IS_BASIC(self)){ response_size = thttp_auth_basic_response(username, password, &response); } else{ TSK_DEBUG_ERROR("%s not supported as scheme.", self->scheme); goto bail; } #define THTTP_AUTH_COPY_VALUES(hdr) \ hdr->username = tsk_strdup(username); \ hdr->scheme = tsk_strdup(self->scheme); \ hdr->realm = tsk_strdup(self->realm); \ hdr->nonce = tsk_strdup(self->nonce); \ hdr->qop = tsk_strdup(self->qop); \ hdr->opaque = tsk_strdup(self->opaque); \ hdr->algorithm = self->algorithm ? tsk_strdup(self->algorithm) : tsk_strdup("MD5"); \ hdr->cnonce = self->nc? tsk_strdup(self->cnonce) : 0; \ hdr->uri = tsk_strdup(uristring); \ hdr->nc = self->nc? tsk_strdup(nc) : 0; \ hdr->response = tsk_strndup(response, response_size); \ if (self->isproxy){ thttp_header_Proxy_Authorization_t *proxy_auth = thttp_header_authorization_create(); // Very bad way to create Proxy_auth header. THTTP_HEADER(proxy_auth)->type = thttp_htype_Proxy_Authorization; THTTP_AUTH_COPY_VALUES(proxy_auth); header = THTTP_HEADER(proxy_auth); } else{ thttp_header_Authorization_t *auth = thttp_header_authorization_create(); THTTP_AUTH_COPY_VALUES(auth); header = THTTP_HEADER(auth); } bail: TSK_FREE(uristring); TSK_FREE(response); return header; #undef THTTP_AUTH_COPY_VALUES }
int tmedia_qos_tline_e2e_to_sdp(const tmedia_qos_tline_e2e_t* self, tsdp_header_M_t* m) { /* RFC 3312 - 5.1.1 SDP encoding For the end-to-end status type, the user agent MUST generate one current status line with the tag "e2e" for the media stream. If the strength-tags for both directions are equal (e.g., both "mandatory") in the transaction status table, the user agent MUST add one desired status line with the tag "sendrecv". If both tags are different, the user agent MUST include two desired status lines, one with the tag "send" and the other with the tag "recv". */ char* temp = tsk_null; if(!self || !m){ TSK_DEBUG_ERROR("invalid parameter"); return -1; } /* Example a=curr:qos e2e none a=des:qos mandatory e2e sendrecv */ /* curr */ tsk_sprintf(&temp, "qos e2e %s", (self->recv.current && self->send.current) ? "sendrecv" : (self->recv.current ? "recv" : (self->send.current ? "send" : "none"))); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("curr", temp), tsk_null); TSK_FREE(temp); /* des */ if(self->recv.strength == self->send.strength){ /* sendrecv */ tsk_sprintf(&temp, "qos %s e2e sendrecv", tmedia_qos_strength_tostring(self->recv.strength)); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("des", temp), tsk_null); TSK_FREE(temp); } else{ /* send */ tsk_sprintf(&temp, "qos %s e2e send", tmedia_qos_strength_tostring(self->send.strength)); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("des", temp), tsk_null); TSK_FREE(temp); /* recv */ tsk_sprintf(&temp, "qos %s e2e recv", tmedia_qos_strength_tostring(self->recv.strength)); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("des", temp), tsk_null); TSK_FREE(temp); } /* conf (should not request confirm on "send" direction)*/ if(self->recv.confirm){ tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("conf", "qos e2e recv"), tsk_null); } return 0; }
/**@ingroup tmedia_codec_group * Serialize a list of codecs to sdp (m= line) message.<br> * Will add: fmt, rtpmap and fmtp. * @param codecs The list of codecs to convert * @param m The destination * @retval Zero if succeed and non-zero error code otherwise */ int tmedia_codec_to_sdp(const tmedia_codecs_L_t* codecs, tsdp_header_M_t* m) { const tsk_list_item_t* item; const tmedia_codec_t* codec; char *fmtp, *rtpmap, *imageattr; tsk_bool_t is_audio, is_video, is_text; int ret; if(!m) { TSK_DEBUG_ERROR("Invalid parameter"); return -1; } is_audio = tsk_striequals(m->media, "audio"); is_video = tsk_striequals(m->media, "video"); is_text = tsk_striequals(m->media, "text"); tsk_list_foreach(item, codecs) { const char *neg_format; codec = item->data; /* add fmt */ neg_format = codec->neg_format? codec->neg_format : codec->format; if((ret = tsdp_header_M_add_fmt(m, neg_format))) { TSK_DEBUG_ERROR("Failed to add format"); return ret; } if(is_audio || is_video || is_text) { char* temp = tsk_null; /* add rtpmap attributes */ if((rtpmap = tmedia_codec_get_rtpmap(codec))) { tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("rtpmap", rtpmap), tsk_null); TSK_FREE(rtpmap); } /* add 'imageattr' attributes */ if((imageattr = tmedia_codec_sdp_att_get(codec, "imageattr"))) { tsk_sprintf(&temp, "%s %s", neg_format, imageattr); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("imageattr", temp), tsk_null); TSK_FREE(temp); TSK_FREE(imageattr); } /* add fmtp attributes */ if((fmtp = tmedia_codec_sdp_att_get(codec, "fmtp"))) { if(is_video && tmedia_defaults_get_screen_x() > 0 && tmedia_defaults_get_screen_y() > 0) { tsk_sprintf(&temp, "%s %s;sx=%d;sy=%d", neg_format, fmtp, tmedia_defaults_get_screen_x(), tmedia_defaults_get_screen_y());//doubango clients } else { tsk_sprintf(&temp, "%s %s", neg_format, fmtp); } tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("fmtp", temp), tsk_null); TSK_FREE(temp); TSK_FREE(fmtp); } /* special case for T.140 + red */ if(is_text && tsk_striequals(codec->format, TMEDIA_CODEC_FORMAT_RED)) { const tmedia_codec_t* codec_t140 = tsk_list_find_object_by_pred(codecs, __pred_find_codec_by_format, TMEDIA_CODEC_FORMAT_T140); if(codec_t140) { const char* neg_format_t140 = codec_t140->neg_format? codec_t140->neg_format : codec_t140->format; tsk_sprintf(&temp, "%s %s/%s/%s/%s", neg_format, neg_format_t140, neg_format_t140, neg_format_t140, neg_format_t140); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("fmtp", temp), tsk_null); TSK_FREE(temp); } } } } return 0; }
int tmedia_qos_tline_segmented_to_sdp(const tmedia_qos_tline_segmented_t* self, tsdp_header_M_t* m) { /* RFC 3312 - 5.1.1 SDP encoding For the segmented status type, the user agent MUST generate two current status lines: one with the tag "local" and the other with the tag "remote". The user agent MUST add one or two desired status lines per segment (i.e., local and remote). If, for a particular segment (local or remote), the tags for both directions in the transaction status table are equal (e.g., both "mandatory"), the user agent MUST add one desired status line with the tag "sendrecv". If both tags are different, the user agent MUST include two desired status lines, one with the tag "send" and the other with the tag "recv". */ char* temp = tsk_null; if(!self || !m){ TSK_DEBUG_ERROR("invalid parameter"); return -1; } /* Example a=curr:qos local none a=curr:qos remote none a=des:qos optional remote send a=des:qos none remote recv a=des:qos none local sendrecv */ /* curr:local */ tsk_sprintf(&temp, "qos local %s", (self->local_recv.current && self->local_send.current) ? "sendrecv" : (self->local_recv.current ? "recv" : (self->local_send.current ? "send" : "none"))); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("curr", temp), tsk_null); TSK_FREE(temp); /* curr:remote */ tsk_sprintf(&temp, "qos remote %s", (self->remote_recv.current && self->remote_send.current) ? "sendrecv" : (self->remote_recv.current ? "recv" : (self->remote_send.current ? "send" : "none"))); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("curr", temp), tsk_null); TSK_FREE(temp); /* des:local */ if(self->local_recv.strength == self->local_send.strength){ /* sendrecv */ tsk_sprintf(&temp, "qos %s local sendrecv", tmedia_qos_strength_tostring(self->local_send.strength)); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("des", temp), tsk_null); TSK_FREE(temp); } else{ /* send */ tsk_sprintf(&temp, "qos %s local send", tmedia_qos_strength_tostring(self->local_send.strength)); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("des", temp), tsk_null); TSK_FREE(temp); /* recv */ tsk_sprintf(&temp, "qos %s local recv", tmedia_qos_strength_tostring(self->local_recv.strength)); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("des", temp), tsk_null); TSK_FREE(temp); } /* des:remote */ if(self->remote_recv.strength == self->remote_send.strength){ /* sendrecv */ tsk_sprintf(&temp, "qos %s remote sendrecv", tmedia_qos_strength_tostring(self->remote_send.strength)); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("des", temp), tsk_null); TSK_FREE(temp); } else{ /* send */ tsk_sprintf(&temp, "qos %s remote send", tmedia_qos_strength_tostring(self->remote_send.strength)); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("des", temp), tsk_null); TSK_FREE(temp); /* recv */ tsk_sprintf(&temp, "qos %s remote recv", tmedia_qos_strength_tostring(self->remote_recv.strength)); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("des", temp), tsk_null); TSK_FREE(temp); } /* conf */ if(self->remote_recv.confirm || self->remote_send.confirm){ tsk_sprintf(&temp, "qos remote %s", (self->remote_recv.confirm && self->remote_send.confirm) ? "sendrecv" : (self->remote_recv.confirm ? "recv" : (self->remote_send.confirm ? "send" : "none"))); tsdp_header_M_add_headers(m, TSDP_HEADER_A_VA_ARGS("conf", temp), tsk_null); TSK_FREE(temp); } return 0; }
int tipsec_set_SAs(tipsec_context_xp_t* ctx_xp) { int ret = -1; FILE* file = NULL; char* str = NULL; if(!ctx_xp){ goto bail; } if(TIPSEC_CONTEXT(ctx_xp)->state != state_full){ TSK_DEBUG_ERROR("IPSec context is in the wrong state."); ret = -3; goto bail; } if(!(file = fopen(TINYIPSEC_IPSEC6_FILE_SAD, "wb+"))){ TSK_DEBUG_ERROR("Failed to open file [%s].", TINYIPSEC_IPSEC6_FILE_SAD); ret = -4; goto bail; } tsk_sprintf(&str, TINYIPSEC_IPSEC6_TEMPLATE_SA, /* PC -> US */ "1", // SAEntry TIPSEC_CONTEXT(ctx_xp)->spi_us, // SPI TIPSEC_CONTEXT(ctx_xp)->addr_local, // SADestIPAddr "POLICY", // DestIPAddr "POLICY", // SrcIPAddr "POLICY", // Protocol "POLICY", // DestPort "POLICY", // SrcPort TINYIPSEC_XP_GET_ALGO(TIPSEC_CONTEXT(ctx_xp)->alg), // AuthAlg TINYIPSEC_IPSEC6_FILE_KEY, // KeyFile "INBOUND", // Direction "0", /* SecPolicyIndex */ /* US -> PC */ "2", // SAEntry TIPSEC_CONTEXT(ctx_xp)->spi_pc, // SPI TIPSEC_CONTEXT(ctx_xp)->addr_remote, // SADestIPAddr "POLICY", // DestIPAddr "POLICY", // SrcIPAddr "POLICY", // Protocol "POLICY", // DestPort "POLICY", // SrcPort TINYIPSEC_XP_GET_ALGO(TIPSEC_CONTEXT(ctx_xp)->alg), // AuthAlg TINYIPSEC_IPSEC6_FILE_KEY, // KeyFile "OUTBOUND", // Direction "0", /* SecPolicyIndex */ /* PS -> UC */ "3", // SAEntry TIPSEC_CONTEXT(ctx_xp)->spi_uc, // SPI TIPSEC_CONTEXT(ctx_xp)->addr_local, // SADestIPAddr "POLICY", // DestIPAddr "POLICY", // SrcIPAddr "POLICY", // Protocol "POLICY", // DestPort "POLICY", // SrcPort TINYIPSEC_XP_GET_ALGO(TIPSEC_CONTEXT(ctx_xp)->alg), // AuthAlg TINYIPSEC_IPSEC6_FILE_KEY, // KeyFile "INBOUND", // Direction "0", /* SecPolicyIndex */ /* UC -> PS */ "4", // SAEntry TIPSEC_CONTEXT(ctx_xp)->spi_ps, // SPI TIPSEC_CONTEXT(ctx_xp)->addr_remote, // SADestIPAddr "POLICY", // DestIPAddr "POLICY", // SrcIPAddr "POLICY", // Protocol "POLICY", // DestPort "POLICY", // SrcPort TINYIPSEC_XP_GET_ALGO(TIPSEC_CONTEXT(ctx_xp)->alg), // AuthAlg TINYIPSEC_IPSEC6_FILE_KEY, // KeyFile "OUTBOUND", // Direction "0" /* SecPolicyIndex */ ); fwrite(str, tsk_strlen(str), sizeof(uint8_t), file); ret = 0; bail: if(file){ fclose(file); } if(str){ TSK_FREE(str); } return ret; }
int tipsec_set_SPDs(tipsec_context_xp_t* ctx_xp) { int ret = -1; FILE* file = NULL; char* str = NULL; if(!ctx_xp){ goto bail; } if(TIPSEC_CONTEXT(ctx_xp)->state != state_full){ TSK_DEBUG_ERROR("IPSec context is in the wrong state."); ret = -3; goto bail; } if(!(file = fopen(TINYIPSEC_IPSEC6_FILE_SPD, "wb+"))){ TSK_DEBUG_ERROR("Failed to open file [%s].", TINYIPSEC_IPSEC6_FILE_SPD); ret = -4; goto bail; } tsk_sprintf(&str, TINYIPSEC_IPSEC6_TEMPLATE_POLICY, /* UC -> PS */ TINYIPSEC_IPSEC6_UCPS_POLICY, TIPSEC_CONTEXT(ctx_xp)->addr_remote, TIPSEC_CONTEXT(ctx_xp)->addr_local, TINYIPSEC_XP_GET_IPPROTO(TIPSEC_CONTEXT(ctx_xp)->ipproto), TIPSEC_CONTEXT(ctx_xp)->port_ps, TIPSEC_CONTEXT(ctx_xp)->port_uc, TINYIPSEC_XP_GET_PROTO(TIPSEC_CONTEXT(ctx_xp)->protocol), TINYIPSEC_XP_GET_MODE(TIPSEC_CONTEXT(ctx_xp)->mode), "*", /* RemoteGWIPAddr */ "NONE", /* SABundleIndex */ "BIDIRECT", /* Direction */ "APPLY", /* Action */ "0", /* InterfaceIndex */ /* US -> PC */ TINYIPSEC_IPSEC6_USPC_POLICY, TIPSEC_CONTEXT(ctx_xp)->addr_remote, TIPSEC_CONTEXT(ctx_xp)->addr_local, TINYIPSEC_XP_GET_IPPROTO(TIPSEC_CONTEXT(ctx_xp)->ipproto), TIPSEC_CONTEXT(ctx_xp)->port_pc, TIPSEC_CONTEXT(ctx_xp)->port_us, TINYIPSEC_XP_GET_PROTO(TIPSEC_CONTEXT(ctx_xp)->protocol), TINYIPSEC_XP_GET_MODE(TIPSEC_CONTEXT(ctx_xp)->mode), "*", /* RemoteGWIPAddr */ "NONE", /* SABundleIndex */ "BIDIRECT", /* Direction */ "APPLY", /* Action */ "0" /* InterfaceIndex */ ); fwrite(str, tsk_strlen(str), sizeof(uint8_t), file); ret = 0; bail: if(file){ fclose(file); } if(str){ TSK_FREE(str); } return ret; }
static int populate_lo(tdav_session_msrp_t* self, tsk_bool_t initial) { if(!self || !TMEDIA_SESSION(self)->M.lo){ TSK_DEBUG_ERROR("Invalid parameter"); return -1; } if(initial){ tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("setup", setup_to_string(self->setup)), tsk_null ); if(self->accept_types || self->neg_accept_type){ /* a=accept-types:message/CPIM application/octet-stream */ tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("accept-types", self->accept_types ? self->accept_types : self->neg_accept_type), tsk_null); } if(self->accept_w_types || self->neg_accept_w_type){ /* a=accept-wrapped-types:application/octet-stream */ tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("accept-wrapped-types", self->accept_w_types ? self->accept_w_types : self->neg_accept_w_type), tsk_null); } /*=== File Transfer ===*/ if(self->file.path){ /* Compute default 'file-selector' */ if(!self->file.selector && !TMEDIA_SESSION(self)->M.ro){ int index = tsk_strLastIndexOf(self->file.path, tsk_strlen(self->file.path), "\\"); if(index == -1){ index = tsk_strLastIndexOf(self->file.path, tsk_strlen(self->file.path), "/"); } index++; tsk_sprintf(&self->file.selector, "name:\"%s\" type:application/octet-stream", (self->file.path + index)); } /* Compute default 'file-transfer-id' */ if(!self->file.transfer_id && !TMEDIA_SESSION(self)->M.ro){ tsk_istr_t rand_string; tsk_strrandom(&rand_string); self->file.transfer_id = tsk_strdup(rand_string); } tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("sendonly", tsk_null), tsk_null); } else{ tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("sendrecv", tsk_null), tsk_null); } if(self->file.selector){ /* a=file-selector:name:"test.pcap" type:application/octet-stream size:11376 hash:sha-1:8D:55:24:2B:F4:F9:9B:A2:54:A3:5B:91:00:15:9E:A3:D4:48:D7:DF */ tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("file-selector", self->file.selector), tsk_null); } if(self->file.transfer_id){ /* a=file-transfer-id:vscxggbwkfnqduxwfnfozvsrtkjprepg */ tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("file-transfer-id", self->file.transfer_id), tsk_null); } if(self->file.disposition){ /* a=file-disposition:attachment */ tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("file-disposition", self->file.disposition), tsk_null); } if(self->file.date){ /* a=file-date:creation:2010-02-13T17:50:31.763Z */ tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("file-date", self->file.date), tsk_null); } if(self->file.icon){ /* a=file-icon:cid:[email protected] */ tsdp_header_M_add_headers(TMEDIA_SESSION(self)->M.lo, TSDP_HEADER_A_VA_ARGS("file-icon", self->file.icon), tsk_null); } } return 0; }
tnet_fd_t tnet_transport_connectto_3(const tnet_transport_handle_t *handle, struct tnet_socket_s* socket, const char* host, tnet_port_t port, tnet_socket_type_t type) { tnet_transport_t *transport = (tnet_transport_t*)handle; struct sockaddr_storage to; int status = -1; tnet_fd_t fd = socket ? socket->fd : TNET_INVALID_FD; tnet_tls_socket_handle_t* tls_handle = tsk_null; tsk_bool_t owe_socket = socket ? tsk_false : tsk_true; tsk_bool_t use_proxy = TNET_SOCKET_TYPE_IS_STREAM(type); const char* to_host = host; tnet_port_t to_port = port; tnet_socket_type_t to_type = type; tnet_proxyinfo_t* proxy_info = tsk_null; if (!transport || !transport->master) { TSK_DEBUG_ERROR("Invalid transport handle"); goto bail; } if ((TNET_SOCKET_TYPE_IS_STREAM(transport->master->type) && !TNET_SOCKET_TYPE_IS_STREAM(type)) || (TNET_SOCKET_TYPE_IS_DGRAM(transport->master->type) && !TNET_SOCKET_TYPE_IS_DGRAM(type))) { TSK_DEBUG_ERROR("Master/destination types mismatch [%u/%u]", transport->master->type, type); goto bail; } if (use_proxy) { // auto-detect the proxy if (transport->proxy.auto_detect) { char* url = tsk_null; // The proxy detection implementations are designed for a browser and expect a "http://" or "https://" schemes (will work with socks). tsk_sprintf(&url, "%s://%s:%d", TNET_SOCKET_TYPE_IS_TLS(to_type) ? "https" : "http", to_host, to_port); proxy_info = tnet_proxydetect_get_info_fast(url, to_type); TSK_FREE(url); } // fall-back to the hard proxy if auto-detection failed if (!tnet_proxyinfo_is_valid(proxy_info) && tnet_proxyinfo_is_valid(transport->proxy.info)) { proxy_info = tsk_object_ref(transport->proxy.info); } } use_proxy &= tnet_proxyinfo_is_valid(proxy_info); if (use_proxy) { if (tnet_proxy_node_is_nettransport_supported(proxy_info->type, type)) { to_host = proxy_info->hostname; to_port = proxy_info->port; // SOCKS still doesn't define RFC for SSL security (https://tools.ietf.org/html/draft-ietf-aft-socks-ssl-00) but Kerberos6 authentication is supported if (proxy_info->type == tnet_proxy_type_http || proxy_info->type == tnet_proxy_type_socks4 || proxy_info->type == tnet_proxy_type_socks4a || proxy_info->type == tnet_proxy_type_socks5) { // Send CONNET to the proxy using unsecure connection then begin SSL handshaking if needed TNET_SOCKET_TYPE_UNSET(to_type, TLS); // Make the type unsecure (will keep other flags-e.g. IP version-) TNET_SOCKET_TYPE_SET(to_type, TCP); // Use plain TCP } } else { // Not an error. TSK_DEBUG_INFO("No proxy plugin to handle network transport type = %d", type); use_proxy = tsk_false; } } TSK_DEBUG_INFO("tnet_transport_connectto_3(host=%s, port=%d, type=%d, fd=%d, use_proxy=%d, to_host=%s, to_port=%d, to_type=%d, proxy_type=%d)" , host, port, type, fd, use_proxy, to_host, to_port, to_type, proxy_info ? proxy_info->type : 0); /* Init destination sockaddr fields */ if ((status = tnet_sockaddr_init(to_host, to_port, to_type, &to))) { TSK_DEBUG_ERROR("Invalid HOST/PORT [%s/%u]", host, port); goto bail; } if (TNET_SOCKET_TYPE_IS_IPV46(type)) { /* Update the type (unambiguously) */ if (to.ss_family == AF_INET6) { TNET_SOCKET_TYPE_SET_IPV6Only(type); } else { TNET_SOCKET_TYPE_SET_IPV4Only(type); } } /* * STREAM ==> create new socket and connect it to the remote host. * DGRAM ==> connect the master to the remote host. */ if (fd == TNET_INVALID_FD) { // Create client socket descriptor. if ((status = tnet_sockfd_init(transport->local_host, TNET_SOCKET_PORT_ANY, to_type, &fd))) { TSK_DEBUG_ERROR("Failed to create new sockfd."); goto bail; } } if ((status = tnet_sockfd_connectto(fd, (const struct sockaddr_storage *)&to))) { if (fd != transport->master->fd) { tnet_sockfd_close(&fd); } goto bail; } else { static const tsk_bool_t __isClient = tsk_true; if (TNET_SOCKET_TYPE_IS_TLS(to_type) || TNET_SOCKET_TYPE_IS_WSS(to_type)) { #if HAVE_OPENSSL tls_handle = tnet_tls_socket_create(fd, transport->tls.ctx_client); if (socket) { TSK_OBJECT_SAFE_FREE(socket->tlshandle); socket->tlshandle = tsk_object_ref(tls_handle); } if ((status = tnet_tls_socket_connect(tls_handle))) { tnet_sockfd_close(&fd); goto bail; } #endif } /* Add the socket */ // socket must be added after connect() otherwise many Linux systems will return POLLHUP as the fd is not active yet if ((status = tnet_transport_add_socket_2(handle, fd, to_type, owe_socket, __isClient, tls_handle, host, port, proxy_info))) { TNET_PRINT_LAST_ERROR("Failed to add new socket"); tnet_sockfd_close(&fd); goto bail; } } bail: TSK_OBJECT_SAFE_FREE(tls_handle); TSK_OBJECT_SAFE_FREE(proxy_info); return status == 0 ? fd : TNET_INVALID_FD; }
const tsdp_header_M_t* tdav_session_msrp_get_lo(tmedia_session_t* self) { tdav_session_msrp_t* msrp; tsk_bool_t changed = tsk_false; const char* proto = "TCP/MSRP"; const char* sheme = "msrp"; TSK_DEBUG_INFO("tdav_session_msrp_get_lo"); if(!self || !self->plugin){ TSK_DEBUG_ERROR("Invalid parameter"); return tsk_null; } msrp = (tdav_session_msrp_t*)self; if(!msrp->transport){ TSK_DEBUG_ERROR("Not prepared"); return tsk_null; } if(/*TNET_SOCKET_TYPE_IS_TLS(type)*/ tsk_false){ proto = "TCP/TLS/MSRP"; sheme = "msrps"; } if(self->ro_changed && self->M.lo){ /* Codecs */ tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "fmtp"); tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "rtpmap"); tsk_list_clear_items(self->M.lo->FMTs); /* QoS */ tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "curr"); tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "des"); tsdp_header_A_removeAll_by_field(self->M.lo->Attributes, "conf"); } changed = (self->ro_changed || !self->M.lo); if(!self->M.lo){ tsk_istr_t id; char* path = tsk_null; tnet_ip_t ip = "0.0.0.0"; tnet_port_t port = 0; tsk_strrandom(&id); tnet_transport_get_public_ip_n_port(msrp->transport, msrp->transport->master->fd, &ip, &port); tsk_sprintf(&path, "%s://%s:%u/%s;tcp", sheme, ip, port, id); //tcp is ok even if tls is used. if((self->M.lo = tsdp_header_M_create(self->plugin->media, port, proto))){ tmsrp_uri_t* uri; tsdp_header_M_add_headers(self->M.lo, TSDP_FMT_VA_ARGS("*"), TSDP_HEADER_C_VA_ARGS("IN", msrp->useIPv6 ? "IP6" : "IP4", ip), TSDP_HEADER_A_VA_ARGS("path", path), tsk_null); if((uri = tmsrp_uri_parse(path, tsk_strlen(path)))){ TSK_OBJECT_SAFE_FREE(msrp->config->From_Path); msrp->config->From_Path = tmsrp_header_From_Path_create(uri); TSK_OBJECT_SAFE_FREE(uri); } } TSK_FREE(path); if(self->M.ro){ /* We are probably about to send 2xx INVITE(sdp) */ /* [OMA-TS-SIMPLE_IM-V1_0-20100322-C] - 5.8.1 Negotiate direction of the MSRP connection setup Offer Answer ________________ active passive / holdconn passive active / holdconn actpass active / passive / holdconn holdconn holdconn */ const tsdp_header_A_t* A; if((A = tsdp_header_M_findA(self->M.ro, "setup"))){ tdav_msrp_setup_t setup = setup_from_string(A->value); switch(setup){ case msrp_setup_passive: msrp->setup = msrp_setup_active; break; case msrp_setup_actpass: case msrp_setup_active: msrp->setup = msrp_setup_passive; break; } tsdp_header_M_add_headers(self->M.lo, TSDP_HEADER_A_VA_ARGS("connection", "new"), tsk_null ); } msrp->offerer = tsk_false; } else{ /* We are probably about to send initial INVITE */ tsdp_header_M_add_headers(self->M.lo, TSDP_HEADER_A_VA_ARGS("connection", "new"), tsk_null ); msrp->offerer = tsk_true; } /* Other SDP fields */ populate_lo(msrp, tsk_true); } // !lo return self->M.lo; }
int tdav_init() { int ret = 0; if(__b_initialized) { TSK_DEBUG_INFO("TINYDAV already initialized"); return 0; } /* === OS specific === */ #if TDAV_UNDER_WINDOWS if ((ret = tdav_win32_init())) { return ret; } #elif TDAV_UNDER_APPLE if ((ret = tdav_apple_init())) { return ret; } #endif /* === Initialize ffmpeg === */ #if HAVE_FFMPEG # if LIBAVCODEC_VERSION_MAJOR <= 53 avcodec_init(); # endif #endif /* === stand-alone plugins === */ #if TDAV_HAVE_PLUGIN_EXT_WIN32 { tsk_size_t plugins_count = 0; char* full_path = tsk_null; // Loading plugins from ActiveX fails when using relative path. /* WASAPI (Audio consumer, Audio producer) */ #if 0 // disable WASAPI by default (AEC issue because of code#consumer rate mismatch) if(tdav_win32_is_winvista_or_later()) { tsk_sprintf(&full_path, "%s/pluginWASAPI.dll", tdav_get_current_directory_const()); if(tsk_plugin_file_exist(full_path) && (__dll_plugin_wasapi = tsk_plugin_create(full_path))) { plugins_count += tmedia_plugin_register(__dll_plugin_wasapi, tsk_plugin_def_type_all, tsk_plugin_def_media_type_all); } } #endif /* CUDA (H.264 codec) */ #if 1 // Enable CUDA by default tsk_sprintf(&full_path, "%s/pluginCUDA.dll", tdav_get_current_directory_const()); // CUDA works on all Windows versions if(tsk_plugin_file_exist(full_path) && (__dll_plugin_cuda = tsk_plugin_create(full_path))) { plugins_count += tmedia_plugin_register(__dll_plugin_cuda, tsk_plugin_def_type_all, tsk_plugin_def_media_type_all); } #endif /* Microsoft Desktop Duplication API (Screen capture) */ if (tdav_win32_is_win8_or_later()) { tsk_sprintf(&full_path, "%s/pluginWinDD.dll", tdav_get_current_directory_const()); if (tsk_plugin_file_exist(full_path) && (__dll_plugin_dd = tsk_plugin_create(full_path))) { plugins_count += tmedia_plugin_register(__dll_plugin_dd, tsk_plugin_def_type_all, tsk_plugin_def_media_type_all); } } /* Media Foundation (Video converter, Video consumer, Video producer, Microsoft H.264 codec, Intel Quick Sync H.264 codec) */ if(tdav_win32_is_win7_or_later()) { tsk_sprintf(&full_path, "%s/pluginWinMF.dll", tdav_get_current_directory_const()); if(tsk_plugin_file_exist(full_path) && (__dll_plugin_mf = tsk_plugin_create(full_path))) { plugins_count += tmedia_plugin_register(__dll_plugin_mf, tsk_plugin_def_type_all, tsk_plugin_def_media_type_all); } } /* DirectShow (Video consumer, Video producer) */ if (tdav_win32_is_winxp_or_later()) { tsk_sprintf(&full_path, "%s/pluginDirectShow.dll", tdav_get_current_directory_const()); if (tsk_plugin_file_exist(full_path) && (__dll_plugin_dshow = tsk_plugin_create(full_path))) { plugins_count += tmedia_plugin_register(__dll_plugin_dshow, tsk_plugin_def_type_all, tsk_plugin_def_media_type_all); } } /* Audio DSP (Resampler, AEC, NS, AGC...) */ if (tdav_win32_is_winvista_or_later()) { tsk_sprintf(&full_path, "%s/pluginWinAudioDSP.dll", tdav_get_current_directory_const()); if(tsk_plugin_file_exist(full_path) && (__dll_plugin_audio_dsp = tsk_plugin_create(full_path))) { plugins_count += tmedia_plugin_register(__dll_plugin_audio_dsp, tsk_plugin_def_type_all, tsk_plugin_def_media_type_all); } } /* IPSec implementation using Windows Filtering Platform (WFP) */ #if !defined(HAVE_TINYIPSEC) || HAVE_TINYIPSEC if (tdav_win32_is_winvista_or_later()) { tsk_sprintf(&full_path, "%s/pluginWinIPSecVista.dll", tdav_get_current_directory_const()); if (tsk_plugin_file_exist(full_path) && (tipsec_plugin_register_file(full_path, &__dll_plugin_ipsec_wfp) == 0)) { plugins_count += 1; // at least one __b_ipsec_supported = tsk_true; } } #endif TSK_FREE(full_path); TSK_DEBUG_INFO("Windows stand-alone plugins loaded = %u", plugins_count); } #endif /* === Register media contents === */ tmedia_content_plugin_register("text/html", tmedia_content_dummy_plugin_def_t); tmedia_content_plugin_register("text/plain", tmedia_content_dummy_plugin_def_t); tmedia_content_plugin_register("application/octet-stream", tmedia_content_dummy_plugin_def_t); tmedia_content_plugin_register("message/CPIM", tmedia_content_cpim_plugin_def_t); /* To be implemented tmedia_content_plugin_register("message/sipfrag", tmedia_content_sipfrag_plugin_def_t); tmedia_content_plugin_register("multipart/digest", tmedia_content_multipart_plugin_def_t); tmedia_content_plugin_register("multipart/mixed", tmedia_content_multipart_plugin_def_t); tmedia_content_plugin_register("multipart/related", tmedia_content_multipart_plugin_def_t); tmedia_content_plugin_register("multipart/alternative", tmedia_content_multipart_plugin_def_t); tmedia_content_plugin_register("multipart/encrypted", tmedia_content_multipart_plugin_def_t); tmedia_content_plugin_register("multipart/parallel", tmedia_content_multipart_plugin_def_t); tmedia_content_plugin_register("multipart/signed", tmedia_content_multipart_plugin_def_t); */ /* === Register sessions === */ tmedia_session_plugin_register(tmedia_session_ghost_plugin_def_t); tmedia_session_plugin_register(tdav_session_audio_plugin_def_t); tmedia_session_plugin_register(tdav_session_video_plugin_def_t); #if !defined(HAVE_TINYMSRP) || HAVE_TINYMSRP tmedia_session_plugin_register(tdav_session_msrp_plugin_def_t); #endif tmedia_session_plugin_register(tdav_session_t140_plugin_def_t); #if !defined(HAVE_TINYBFCP) || HAVE_TINYBFCP tmedia_session_plugin_register(tdav_session_bfcp_plugin_def_t); #endif tmedia_session_plugin_register(tdav_session_bfcpaudio_plugin_def_t); tmedia_session_plugin_register(tdav_session_bfcpvideo_plugin_def_t); /* === Register codecs === */ #if HAVE_FFMPEG avcodec_register_all(); #endif #if !defined(HAVE_TINYMSRP) || HAVE_TINYMSRP tmedia_codec_plugin_register(tdav_codec_msrp_plugin_def_t); #endif tmedia_codec_plugin_register(tdav_codec_t140_plugin_def_t); #if !defined(HAVE_TINYBFCP) || HAVE_TINYBFCP tmedia_codec_plugin_register(tdav_codec_bfcp_plugin_def_t); #endif tmedia_codec_plugin_register(tdav_codec_red_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_g711a_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_g711u_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_g722_plugin_def_t); #if HAVE_OPENCORE_AMR tmedia_codec_plugin_register(tdav_codec_amrnb_oa_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_amrnb_be_plugin_def_t); #endif #if HAVE_BV16 tmedia_codec_plugin_register(tdav_codec_bv16_plugin_def_t); #endif #if HAVE_LIBGSM tmedia_codec_plugin_register(tdav_codec_gsm_plugin_def_t); #endif #if HAVE_ILBC tmedia_codec_plugin_register(tdav_codec_ilbc_plugin_def_t); #endif #if HAVE_LIB_SPEEX tmedia_codec_plugin_register(tdav_codec_speex_nb_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_speex_wb_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_speex_uwb_plugin_def_t); #endif #if HAVE_LIBOPUS tmedia_codec_plugin_register(tdav_codec_opus_plugin_def_t); #endif #if HAVE_G729 tmedia_codec_plugin_register(tdav_codec_g729ab_plugin_def_t); #endif // last: dtmf, ULPFEC and RED tmedia_codec_plugin_register(tdav_codec_dtmf_plugin_def_t); // tmedia_codec_plugin_register(tdav_codec_ulpfec_plugin_def_t); // tmedia_codec_plugin_register(tdav_codec_red_plugin_def_t); #if HAVE_LIBVPX tmedia_codec_plugin_register(tdav_codec_vp8_plugin_def_t); #endif #if HAVE_CUDA #error "Support for H.264 Cuda is deprecated" if(tdav_codec_h264_cuda_is_supported()) { tmedia_codec_plugin_register(tdav_codec_h264_cuda_bp10_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_h264_cuda_bp20_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_h264_cuda_bp30_plugin_def_t); } #endif #if HAVE_OPENH264 tmedia_codec_plugin_register(tdav_codec_h264_cisco_base_plugin_def_t); #endif #if HAVE_FFMPEG if(tdav_codec_ffmpeg_mp4ves_is_supported()) { tmedia_codec_plugin_register(tdav_codec_mp4ves_plugin_def_t); } if(tdav_codec_ffmpeg_h264_is_supported()) { if(!tmedia_codec_plugin_is_registered_2(tmedia_codec_id_h264_bp)) { // could be already registered by stand alone plugins (e.g. pluginWinMF.DLL) tmedia_codec_plugin_register(tdav_codec_h264_base_plugin_def_t); } if(!tmedia_codec_plugin_is_registered_2(tmedia_codec_id_h264_mp)) { // could be already registered by stand alone plugins (e.g. pluginWinMF.DLL) tmedia_codec_plugin_register(tdav_codec_h264_main_plugin_def_t); } } tmedia_codec_plugin_register(tdav_codec_h263p_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_h263pp_plugin_def_t); if(tdav_codec_ffmpeg_theora_is_supported()) { tmedia_codec_plugin_register(tdav_codec_theora_plugin_def_t); } tmedia_codec_plugin_register(tdav_codec_h263_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_h261_plugin_def_t); #elif HAVE_H264_PASSTHROUGH tmedia_codec_plugin_register(tdav_codec_h264_base_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_h264_main_plugin_def_t); #endif #if HAVE_INTEL_MEDIA_SDK tmedia_codec_plugin_register(tdav_codec_h264_intel_base_plugin_def_t); tmedia_codec_plugin_register(tdav_codec_h264_intel_main_plugin_def_t); #endif /* === Register converters === */ // register several convertors and try them all (e.g. LIBYUV only support to/from I420) #if HAVE_LIBYUV tmedia_converter_video_plugin_register(tdav_converter_video_libyuv_plugin_def_t); #endif #if HAVE_FFMPEG || HAVE_SWSSCALE tmedia_converter_video_plugin_register(tdav_converter_video_ffmpeg_plugin_def_t); #endif /* === Register consumers === */ tmedia_consumer_plugin_register(tdav_consumer_t140_plugin_def_t); /* T140 */ #if HAVE_DSOUND_H tmedia_consumer_plugin_register(tdav_consumer_dsound_plugin_def_t); #elif HAVE_WAVE_API tmedia_consumer_plugin_register(tdav_consumer_waveapi_plugin_def_t); #elif HAVE_WASAPI tmedia_consumer_plugin_register(tdav_consumer_wasapi_plugin_def_t); #endif #if TDAV_UNDER_WINDOWS && !TDAV_UNDER_WINDOWS_RT // Windows GDI tmedia_consumer_plugin_register(tdav_consumer_video_gdi_plugin_def_t); #endif #if HAVE_WINM // Windows Media (WP8) tmedia_consumer_plugin_register(tdav_consumer_winm_plugin_def_t); #endif #if HAVE_ALSA_ASOUNDLIB_H // Linux tmedia_consumer_plugin_register(tdav_consumer_alsa_plugin_def_t); #endif #if HAVE_LINUX_SOUNDCARD_H // Linux tmedia_consumer_plugin_register(tdav_consumer_oss_plugin_def_t); #endif #if HAVE_COREAUDIO_AUDIO_UNIT // CoreAudio based on AudioUnit tmedia_consumer_plugin_register(tdav_consumer_audiounit_plugin_def_t); #elif HAVE_COREAUDIO_AUDIO_QUEUE // CoreAudio based on AudioQueue tmedia_consumer_plugin_register(tdav_consumer_audioqueue_plugin_def_t); #endif #if HAVE_OSS_H tmedia_consumer_plugin_register(tmedia_consumer_oss_plugin_def_t); #endif /* === Register producers === */ tmedia_producer_plugin_register(tdav_producer_t140_plugin_def_t); /* T140 */ #if HAVE_DSOUND_H // DirectSound tmedia_producer_plugin_register(tdav_producer_dsound_plugin_def_t); #elif HAVE_WAVE_API // WaveAPI tmedia_producer_plugin_register(tdav_producer_waveapi_plugin_def_t); #elif HAVE_WASAPI // WASAPI tmedia_producer_plugin_register(tdav_producer_wasapi_plugin_def_t); #endif #if TDAV_UNDER_WINDOWS && !TDAV_UNDER_WINDOWS_RT // Windows DirectDraw (DirectX) if (tdav_producer_screencast_ddraw_plugin_is_supported()) { tmedia_producer_plugin_register(tdav_producer_screencast_ddraw_plugin_def_t); } #endif #if TDAV_UNDER_WINDOWS && !TDAV_UNDER_WINDOWS_RT // Windows GDI tmedia_producer_plugin_register(tdav_producer_screencast_gdi_plugin_def_t); #endif #if HAVE_WINM // Windows Media (WP8) tmedia_producer_plugin_register(tdav_producer_winm_plugin_def_t); #endif #if HAVE_ALSA_ASOUNDLIB_H // Linux tmedia_producer_plugin_register(tdav_producer_alsa_plugin_def_t); #endif #if HAVE_LINUX_SOUNDCARD_H // Linux tmedia_producer_plugin_register(tdav_producer_oss_plugin_def_t); #endif #if HAVE_LINUX_VIDEODEV2_H // V4L2 (Linux) tmedia_producer_plugin_register(tdav_producer_video_v4l2_plugin_def_t); tmedia_producer_plugin_register(tdav_producer_screencast_v4l2_plugin_def_t); #endif #if HAVE_COREAUDIO_AUDIO_UNIT // CoreAudio based on AudioUnit tmedia_producer_plugin_register(tdav_producer_audiounit_plugin_def_t); #elif HAVE_COREAUDIO_AUDIO_QUEUE // CoreAudio based on AudioQueue tmedia_producer_plugin_register(tdav_producer_audioqueue_plugin_def_t); #endif /* === Register Audio Denoise (AGC, VAD, Noise Suppression and AEC) === */ #if HAVE_WEBRTC && (!defined(HAVE_WEBRTC_DENOISE) || HAVE_WEBRTC_DENOISE) tmedia_denoise_plugin_register(tdav_webrtc_denoise_plugin_def_t); #endif #if HAVE_SPEEX_DSP && (!defined(HAVE_SPEEX_DENOISE) || HAVE_SPEEX_DENOISE) tmedia_denoise_plugin_register(tdav_speex_denoise_plugin_def_t); #endif /* === Register Audio Resampler === */ #if HAVE_SPEEX_DSP && (!defined(HAVE_SPEEX_RESAMPLER) || HAVE_SPEEX_RESAMPLER) tmedia_resampler_plugin_register(tdav_speex_resampler_plugin_def_t); #endif /* === Register Audio/video JitterBuffer === */ #if HAVE_SPEEX_DSP && HAVE_SPEEX_JB tmedia_jitterbuffer_plugin_register(tdav_speex_jitterbuffer_plugin_def_t); #else tmedia_jitterbuffer_plugin_register(tdav_speakup_jitterbuffer_plugin_def_t); #endif // collect all codecs before filtering _tdav_codec_plugins_collect(); __b_initialized = tsk_true; return ret; }