コード例 #1
0
ファイル: call_interfaces.c プロジェクト: kupishkis/rtpengine
static int streams_parse_func(char **a, void **ret, void *p) {
	struct stream_params *sp;
	u_int32_t ip;
	int *i;

	i = p;
	sp = g_slice_alloc0(sizeof(*sp));

	SP_SET(sp, SEND);
	SP_SET(sp, RECV);
	sp->protocol = &transport_protocols[PROTO_RTP_AVP];

	ip = inet_addr(a[0]);
	if (ip == -1)
		goto fail;

	in4_to_6(&sp->rtp_endpoint.ip46, ip);
	sp->rtp_endpoint.port = atoi(a[1]);
	sp->index = ++(*i);
	sp->consecutive_ports = 1;

	sp->rtcp_endpoint = sp->rtp_endpoint;
	sp->rtcp_endpoint.port++;

	if (!sp->rtp_endpoint.port && strcmp(a[1], "0"))
		goto fail;

	*ret = sp;
	return 0;

fail:
	ilog(LOG_WARNING, "Failed to parse a media stream: %s:%s", a[0], a[1]);
	g_slice_free1(sizeof(*sp), sp);
	return -1;
}
コード例 #2
0
ファイル: call_interfaces.c プロジェクト: kupishkis/rtpengine
static int addr_parse_udp(struct stream_params *sp, char **out) {
	u_int32_t ip4;
	const char *cp;
	char c;
	int i;

	ZERO(*sp);

	SP_SET(sp, SEND);
	SP_SET(sp, RECV);
	sp->protocol = &transport_protocols[PROTO_RTP_AVP];

	if (out[RE_UDP_UL_ADDR4] && *out[RE_UDP_UL_ADDR4]) {
		ip4 = inet_addr(out[RE_UDP_UL_ADDR4]);
		if (ip4 == -1)
			goto fail;
		in4_to_6(&sp->rtp_endpoint.ip46, ip4);
	}
	else if (out[RE_UDP_UL_ADDR6] && *out[RE_UDP_UL_ADDR6]) {
		if (inet_pton(AF_INET6, out[RE_UDP_UL_ADDR6], &sp->rtp_endpoint.ip46) != 1)
			goto fail;
	}
	else
		goto fail;

	sp->rtp_endpoint.port = atoi(out[RE_UDP_UL_PORT]);
	if (!sp->rtp_endpoint.port && strcmp(out[RE_UDP_UL_PORT], "0"))
		goto fail;

	if (out[RE_UDP_UL_FLAGS] && *out[RE_UDP_UL_FLAGS]) {
		i = 0;
		for (cp =out[RE_UDP_UL_FLAGS]; *cp && i < 2; cp++) {
			c = chrtoupper(*cp);
			if (c == 'E')
				str_init(&sp->direction[i++], "external");
			else if (c == 'I')
				str_init(&sp->direction[i++], "internal");
		}
	}

	if (out[RE_UDP_UL_NUM] && *out[RE_UDP_UL_NUM])
		sp->index = atoi(out[RE_UDP_UL_NUM]);
	if (!sp->index)
		sp->index = 1;
	sp->consecutive_ports = 1;

	sp->rtcp_endpoint = sp->rtp_endpoint;
	sp->rtcp_endpoint.port++;

	return 0;
fail:
	return -1;
}
コード例 #3
0
ファイル: sdp.c プロジェクト: jungle0755/rtpengine
static void __sdp_ice(struct stream_params *sp, struct sdp_media *media) {
	struct sdp_attribute *attr;
	struct attribute_candidate *ac;
	struct ice_candidate *cand;
	GQueue *q;
	GList *ql;

	attr = attr_get_by_id_m_s(media, ATTR_ICE_UFRAG);
	if (!attr)
		return;
	sp->ice_ufrag = attr->value;

	SP_SET(sp, ICE);

	q = attr_list_get_by_id(&media->attributes, ATTR_CANDIDATE);
	if (!q)
		goto no_cand;

	for (ql = q->head; ql; ql = ql->next) {
		attr = ql->data;
		ac = &attr->u.candidate;
		if (!ac->parsed)
			continue;
		cand = g_slice_alloc(sizeof(*cand));
		*cand = ac->cand_parsed;
		g_queue_push_tail(&sp->ice_candidates, cand);
	}

no_cand:
	if ((attr = attr_get_by_id(&media->attributes, ATTR_ICE_OPTIONS))) {
		if (str_str(&attr->value, "trickle") >= 0)
			SP_SET(sp, TRICKLE_ICE);
	}
	else if (is_trickle_ice_address(&sp->rtp_endpoint))
		SP_SET(sp, TRICKLE_ICE);

	if (attr_get_by_id(&media->attributes, ATTR_ICE_LITE))
		SP_SET(sp, ICE_LITE);

	attr = attr_get_by_id_m_s(media, ATTR_ICE_PWD);
	if (attr)
		sp->ice_pwd = attr->value;
}
コード例 #4
0
ファイル: sdp.c プロジェクト: jungle0755/rtpengine
/* XXX split this function up */
int sdp_streams(const GQueue *sessions, GQueue *streams, struct sdp_ng_flags *flags) {
	struct sdp_session *session;
	struct sdp_media *media;
	struct stream_params *sp;
	GList *l, *k;
	const char *errstr;
	int num;
	struct sdp_attribute *attr;

	num = 0;
	for (l = sessions->head; l; l = l->next) {
		session = l->data;

		for (k = session->media_streams.head; k; k = k->next) {
			media = k->data;

			sp = g_slice_alloc0(sizeof(*sp));
			sp->index = ++num;

			errstr = "No address info found for stream";
			if (fill_endpoint(&sp->rtp_endpoint, media, flags, NULL, media->port_num))
				goto error;

			sp->consecutive_ports = media->port_count;
			sp->protocol = transport_protocol(&media->transport);
			sp->type = media->media_type;
			memcpy(sp->direction, flags->direction, sizeof(sp->direction));
			sp->desired_family = flags->address_family;
			bf_set_clear(&sp->sp_flags, SP_FLAG_ASYMMETRIC, flags->asymmetric);
			bf_set_clear(&sp->sp_flags, SP_FLAG_STRICT_SOURCE, flags->strict_source);
			bf_set_clear(&sp->sp_flags, SP_FLAG_MEDIA_HANDOVER, flags->media_handover);

			errstr = "Invalid RTP payload types";
			if (__rtp_payload_types(sp, media))
				goto error;

			/* a=crypto */
			attr = attr_get_by_id(&media->attributes, ATTR_CRYPTO);
			if (attr) {
				sp->crypto.crypto_suite = attr->u.crypto.crypto_suite;
				sp->crypto.mki_len = attr->u.crypto.mki_len;
				if (sp->crypto.mki_len) {
					sp->crypto.mki = malloc(sp->crypto.mki_len);
					memcpy(sp->crypto.mki, attr->u.crypto.mki, sp->crypto.mki_len);
				}
				sp->sdes_tag = attr->u.crypto.tag;
				assert(sizeof(sp->crypto.master_key) >= attr->u.crypto.master_key.len);
				assert(sizeof(sp->crypto.master_salt) >= attr->u.crypto.salt.len);
				memcpy(sp->crypto.master_key, attr->u.crypto.master_key.s,
						attr->u.crypto.master_key.len);
				memcpy(sp->crypto.master_salt, attr->u.crypto.salt.s,
						attr->u.crypto.salt.len);
				sp->crypto.session_params.unencrypted_srtp = attr->u.crypto.unencrypted_srtp;
				sp->crypto.session_params.unencrypted_srtcp = attr->u.crypto.unencrypted_srtcp;
				sp->crypto.session_params.unauthenticated_srtp = attr->u.crypto.unauthenticated_srtp;
			}

			/* a=sendrecv/sendonly/recvonly/inactive */
			SP_SET(sp, SEND);
			SP_SET(sp, RECV);
			if (attr_get_by_id_m_s(media, ATTR_RECVONLY))
				SP_CLEAR(sp, SEND);
			else if (attr_get_by_id_m_s(media, ATTR_SENDONLY))
				SP_CLEAR(sp, RECV);
			else if (attr_get_by_id_m_s(media, ATTR_INACTIVE))
			{
				SP_CLEAR(sp, RECV);
				SP_CLEAR(sp, SEND);
			}

			/* a=setup */
			attr = attr_get_by_id_m_s(media, ATTR_SETUP);
			if (attr) {
				if (attr->u.setup.value == SETUP_ACTPASS
						|| attr->u.setup.value == SETUP_ACTIVE)
					SP_SET(sp, SETUP_ACTIVE);
				if (attr->u.setup.value == SETUP_ACTPASS
						|| attr->u.setup.value == SETUP_PASSIVE)
					SP_SET(sp, SETUP_PASSIVE);
			}

			/* a=fingerprint */
			attr = attr_get_by_id_m_s(media, ATTR_FINGERPRINT);
			if (attr && attr->u.fingerprint.hash_func) {
				sp->fingerprint.hash_func = attr->u.fingerprint.hash_func;
				memcpy(sp->fingerprint.digest, attr->u.fingerprint.fingerprint,
						sp->fingerprint.hash_func->num_bytes);
			}

			__sdp_ice(sp, media);

			/* determine RTCP endpoint */

			if (attr_get_by_id(&media->attributes, ATTR_RTCP_MUX)) {
				SP_SET(sp, RTCP_MUX);
				goto next;
			}

			if (media->port_count != 1)
				goto next;

			attr = attr_get_by_id(&media->attributes, ATTR_RTCP);
			if (!attr) {
				SP_SET(sp, IMPLICIT_RTCP);
				goto next;
			}
			if (attr->u.rtcp.port_num == sp->rtp_endpoint.port
					&& !is_trickle_ice_address(&sp->rtp_endpoint))
			{
				SP_SET(sp, RTCP_MUX);
				goto next;
			}
			errstr = "Invalid RTCP attribute";
			if (fill_endpoint(&sp->rtcp_endpoint, media, flags, &attr->u.rtcp.address,
						attr->u.rtcp.port_num))
				goto error;

next:
			g_queue_push_tail(streams, sp);
		}
	}

	return 0;

error:
	ilog(LOG_WARNING, "Failed to extract streams from SDP: %s", errstr);
	if (sp)
		g_slice_free1(sizeof(*sp), sp);
	return -1;
}