示例#1
0
/*! \brief Function which adds ICE attributes to a media stream */
static void add_ice_to_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, pj_pool_t *pool, pjmedia_sdp_media *media)
{
	struct ast_rtp_engine_ice *ice;
	struct ao2_container *candidates;
	const char *username, *password;
	pj_str_t stmp;
	pjmedia_sdp_attr *attr;
	struct ao2_iterator it_candidates;
	struct ast_rtp_engine_ice_candidate *candidate;

	if (!session->endpoint->media.rtp.ice_support || !(ice = ast_rtp_instance_get_ice(session_media->rtp)) ||
		!(candidates = ice->get_local_candidates(session_media->rtp))) {
		return;
	}

	if ((username = ice->get_ufrag(session_media->rtp))) {
		attr = pjmedia_sdp_attr_create(pool, "ice-ufrag", pj_cstr(&stmp, username));
		media->attr[media->attr_count++] = attr;
	}

	if ((password = ice->get_password(session_media->rtp))) {
		attr = pjmedia_sdp_attr_create(pool, "ice-pwd", pj_cstr(&stmp, password));
		media->attr[media->attr_count++] = attr;
	}

	it_candidates = ao2_iterator_init(candidates, 0);
	for (; (candidate = ao2_iterator_next(&it_candidates)); ao2_ref(candidate, -1)) {
		struct ast_str *attr_candidate = ast_str_create(128);

		ast_str_set(&attr_candidate, -1, "%s %u %s %d %s ", candidate->foundation, candidate->id, candidate->transport,
					candidate->priority, ast_sockaddr_stringify_addr_remote(&candidate->address));
		ast_str_append(&attr_candidate, -1, "%s typ ", ast_sockaddr_stringify_port(&candidate->address));

		switch (candidate->type) {
			case AST_RTP_ICE_CANDIDATE_TYPE_HOST:
				ast_str_append(&attr_candidate, -1, "host");
				break;
			case AST_RTP_ICE_CANDIDATE_TYPE_SRFLX:
				ast_str_append(&attr_candidate, -1, "srflx");
				break;
			case AST_RTP_ICE_CANDIDATE_TYPE_RELAYED:
				ast_str_append(&attr_candidate, -1, "relay");
				break;
		}

		if (!ast_sockaddr_isnull(&candidate->relay_address)) {
			ast_str_append(&attr_candidate, -1, " raddr %s rport", ast_sockaddr_stringify_addr_remote(&candidate->relay_address));
			ast_str_append(&attr_candidate, -1, " %s", ast_sockaddr_stringify_port(&candidate->relay_address));
		}

		attr = pjmedia_sdp_attr_create(pool, "candidate", pj_cstr(&stmp, ast_str_buffer(attr_candidate)));
		media->attr[media->attr_count++] = attr;

		ast_free(attr_candidate);
	}

	ao2_iterator_destroy(&it_candidates);
	ao2_ref(candidates, -1);
}
示例#2
0
struct ast_json *ast_json_ipaddr(const struct ast_sockaddr *addr, enum ast_transport transport_type)
{
	struct ast_str *string = ast_str_alloca(64);

	if (!string) {
		return NULL;
	}

	ast_str_set(&string, 0, (ast_sockaddr_is_ipv4(addr) ||
		ast_sockaddr_is_ipv4_mapped(addr)) ? "IPV4/" : "IPV6/");

	if (transport_type) {
		char *transport_string = NULL;

		/* NOTE: None will be applied if multiple transport types are specified in transport_type */
		switch(transport_type) {
		case AST_TRANSPORT_UDP:
			transport_string = "UDP";
			break;
		case AST_TRANSPORT_TCP:
			transport_string = "TCP";
			break;
		case AST_TRANSPORT_TLS:
			transport_string = "TLS";
			break;
		case AST_TRANSPORT_WS:
			transport_string = "WS";
			break;
		case AST_TRANSPORT_WSS:
			transport_string = "WSS";
			break;
		}

		if (transport_string) {
			ast_str_append(&string, 0, "%s/", transport_string);
		}
	}

	ast_str_append(&string, 0, "%s", ast_sockaddr_stringify_addr(addr));
	ast_str_append(&string, 0, "/%s", ast_sockaddr_stringify_port(addr));

	return ast_json_string_create(ast_str_buffer(string));
}