示例#1
0
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);
		}
	}
示例#2
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;
}
示例#3
0
/** 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;
}
示例#4
0
/**@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;
}
示例#5
0
/**@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;
	}
}
示例#6
0
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;
}
示例#7
0
/**@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;
}
示例#8
0
/**@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;
}
示例#9
0
/**@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;
}
示例#10
0
/**@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;
}
示例#11
0
/**@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;
}
示例#12
0
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;
}
示例#13
0
/**@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;
}
示例#14
0
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;
}
示例#15
0
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
}
示例#16
0
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;
}
示例#17
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;
}
示例#18
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;
}
示例#19
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;
}
示例#20
0
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;
}
示例#21
0
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;
}
示例#22
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;
}
示例#23
0
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;
}
示例#24
0
文件: tdav.c 项目: shanlq/doubango
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;
}