Esempio n. 1
0
void audio_sdp_attr_decode(struct audio *a)
{
	const char *attr;

	if (!a)
		return;

	/* This is probably only meaningful for audio data, but
	   may be used with other media types if it makes sense. */
	attr = sdp_media_rattr(stream_sdpmedia(a->strm), "ptime");
	if (attr) {
		struct autx *tx = &a->tx;
		uint32_t ptime_tx = atoi(attr);

		if (ptime_tx && ptime_tx != a->tx.ptime) {

			info("audio: peer changed ptime_tx %u -> %u\n",
			     a->tx.ptime, ptime_tx);

			tx->ptime = ptime_tx;

			if (tx->ac) {
				tx->psize = 2 * get_framesize(tx->ac,
							      ptime_tx);
			}
		}
	}
}
Esempio n. 2
0
static void sig_hash_decode(struct zrtp_stream_t *stream,
                           const struct sdp_media *m)
{
	const char *attr_val;
	struct pl major, minor, hash;
	uint32_t version;
	int err;
	zrtp_status_t s;

	attr_val = sdp_media_rattr(m, "zrtp-hash");
	if (!attr_val)
		return;

	err = re_regex(attr_val, strlen(attr_val),
	               "[0-9]+.[0-9]2 [0-9a-f]+",
	               &major, &minor, &hash);
	if (err || hash.l < ZRTP_SIGN_ZRTP_HASH_LENGTH) {
		warning("zrtp: malformed zrtp-hash attribute, ignoring...\n");
		return;
	}

	version = pl_u32(&major) * 100 + pl_u32(&minor);
	/* more version checks? */
	if (version < 110) {
		warning("zrtp: zrtp-hash: version (%d) is too low, "
		        "ignoring...", version);
	}

	s = zrtp_signaling_hash_set(stream, hash.p, (uint32_t)hash.l);
	if (s != zrtp_status_ok)
		warning("zrtp: zrtp_signaling_hash_set: status = %d\n", s);
}
Esempio n. 3
0
void audio_sdp_attr_decode(struct audio *a)
{
	const char *attr;

	if (!a)
		return;

	/* This is probably only meaningful for audio data, but
	   may be used with other media types if it makes sense. */
	attr = sdp_media_rattr(stream_sdpmedia(a->strm), "ptime");
	if (attr)
		audio_ptime_tx_set(a, atoi(attr));
}
Esempio n. 4
0
/**
 * Get a remote attribute from the SDP. Try the media-level first,
 * and if it does not exist then try session-level.
 *
 * @param s    SDP Session object
 * @param m    SDP Media object
 * @param name Remote attribute name
 *
 * @return Remote attribute value
 */
const char *sdp_rattr(const struct sdp_session *s, const struct sdp_media *m,
		      const char *name)
{
	const char *x;

	x = sdp_media_rattr(m, name);
	if (x)
		return x;

	x = sdp_session_rattr(s, name);
	if (x)
		return x;

	return NULL;
}
Esempio n. 5
0
static void stream_remote_set(struct stream *s)
{
	struct sa rtcp;

	if (!s)
		return;

	/* RFC 5761 */
	if (s->cfg.rtcp_mux && sdp_media_rattr(s->sdp, "rtcp-mux")) {

		if (!s->rtcp_mux)
			info("%s: RTP/RTCP multiplexing enabled\n",
			     sdp_media_name(s->sdp));
		s->rtcp_mux = true;
	}

	rtcp_enable_mux(s->rtp, s->rtcp_mux);

	sdp_media_raddr_rtcp(s->sdp, &rtcp);

	rtcp_start(s->rtp, s->cname,
		   s->rtcp_mux ? sdp_media_raddr(s->sdp): &rtcp);
}
Esempio n. 6
0
static void stream_remote_set(struct stream *s, const char *cname)
{
	struct sa rtcp;

	if (!s)
		return;

	/* RFC 5761 */
	if (config.avt.rtcp_mux && sdp_media_rattr(s->sdp, "rtcp-mux")) {

		if (!s->rtcp_mux)
			(void)re_printf("%s: RTP/RTCP multiplexing enabled\n",
					sdp_media_name(s->sdp));
		s->rtcp_mux = true;
	}

	rtcp_enable_mux(s->rtp, s->rtcp_mux);

	sdp_media_raddr_rtcp(s->sdp, &rtcp);

	rtcp_start(s->rtp, cname,
		   s->rtcp_mux ? sdp_media_raddr(s->sdp): &rtcp);
}
Esempio n. 7
0
static int alloc(struct menc_media **stp, struct menc_sess *sess,
		 struct rtp_sock *rtp,
		 int proto, void *rtpsock, void *rtcpsock,
		 struct sdp_media *sdpm)
{
	struct menc_st *st;
	const char *rattr = NULL;
	int layer = 10; /* above zero */
	int err = 0;
	bool mux = (rtpsock == rtcpsock);
	(void)sess;
	(void)rtp;

	if (!stp || !sdpm)
		return EINVAL;
	if (proto != IPPROTO_UDP)
		return EPROTONOSUPPORT;

	st = (struct menc_st *)*stp;
	if (!st) {

		st = mem_zalloc(sizeof(*st), destructor);
		if (!st)
			return ENOMEM;

		st->sdpm = mem_ref(sdpm);

		err = sdp_media_set_alt_protos(st->sdpm, 4,
					       "RTP/AVP",
					       "RTP/AVPF",
					       "RTP/SAVP",
					       "RTP/SAVPF");
		if (err)
			goto out;

		if (rtpsock) {
			st->rtpsock = mem_ref(rtpsock);
			err |= udp_register_helper(&st->uh_rtp, rtpsock,
						   layer, send_handler,
						   recv_handler, st);
		}
		if (rtcpsock && !mux) {
			st->rtcpsock = mem_ref(rtcpsock);
			err |= udp_register_helper(&st->uh_rtcp, rtcpsock,
						   layer, send_handler,
						   recv_handler, st);
		}
		if (err)
			goto out;

		/* set our preferred crypto-suite */
		err |= str_dup(&st->crypto_suite, aes_cm_128_hmac_sha1_80);
		if (err)
			goto out;

		err = setup_srtp(st);
		if (err)
			goto out;
	}

	/* SDP handling */

	if (sdp_media_rattr(st->sdpm, "crypto")) {

		rattr = sdp_media_rattr_apply(st->sdpm, "crypto",
					      sdp_attr_handler, st);
		if (!rattr) {
			DEBUG_WARNING("no valid a=crypto attribute from"
				      " remote peer\n");
		}
	}

	if (!rattr)
		err = sdp_enc(st, sdpm, 0, st->crypto_suite);

 out:
	if (err)
		mem_deref(st);
	else
		*stp = (struct menc_media *)st;

	return err;
}
Esempio n. 8
0
/**
 * Get the numerical value from a remote attribute
 *
 * @param m    SDP Media object
 * @param name Remote attribute name
 *
 * @return Numerical value or 0 if not found
 */
uint32_t sdp_media_rattr_u32(const struct sdp_media *m, const char *name)
{
	const char *attr = sdp_media_rattr(m, name);
	return attr ? atoi(attr) : 0;
}
Esempio n. 9
0
static int media_alloc(struct menc_media **stp, struct menc_sess *sess,
		 struct rtp_sock *rtp,
		 struct udp_sock *rtpsock, struct udp_sock *rtcpsock,
	         const struct sa *raddr_rtp,
	         const struct sa *raddr_rtcp,
		 struct sdp_media *sdpm)
{
	struct menc_st *st;
	const char *rattr = NULL;
	int layer = 10; /* above zero */
	int err = 0;
	bool mux = (rtpsock == rtcpsock);
	(void)sess;
	(void)rtp;
	(void)raddr_rtp;
	(void)raddr_rtcp;

	if (!stp || !sdpm || !sess)
		return EINVAL;

	st = (struct menc_st *)*stp;
	if (!st) {

		st = mem_zalloc(sizeof(*st), destructor);
		if (!st)
			return ENOMEM;

		st->sess = sess;
		st->sdpm = mem_ref(sdpm);

		if (0 == str_cmp(sdp_media_proto(sdpm), "RTP/AVP")) {
			err = sdp_media_set_alt_protos(st->sdpm, 4,
						       "RTP/AVP",
						       "RTP/AVPF",
						       "RTP/SAVP",
						       "RTP/SAVPF");
			if (err)
				goto out;
		}

		if (rtpsock) {
			st->rtpsock = mem_ref(rtpsock);
			err |= udp_register_helper(&st->uh_rtp, rtpsock,
						   layer, send_handler,
						   recv_handler, st);
		}
		if (rtcpsock && !mux) {
			st->rtcpsock = mem_ref(rtcpsock);
			err |= udp_register_helper(&st->uh_rtcp, rtcpsock,
						   layer, send_handler,
						   recv_handler, st);
		}
		if (err)
			goto out;

		/* set our preferred crypto-suite */
		err |= str_dup(&st->crypto_suite, preferred_suite);
		if (err)
			goto out;

		rand_bytes(st->key_tx, sizeof(st->key_tx));
	}

	/* SDP handling */

	if (sdp_media_rport(sdpm))
		st->got_sdp = true;

	if (sdp_media_rattr(st->sdpm, "crypto")) {

		rattr = sdp_media_rattr_apply(st->sdpm, "crypto",
					      sdp_attr_handler, st);
		if (!rattr) {
			warning("srtp: no valid a=crypto attribute from"
				" remote peer\n");
		}
	}

	if (!rattr)
		err = sdp_enc(st, sdpm, 1, st->crypto_suite);

 out:
	if (err)
		mem_deref(st);
	else
		*stp = (struct menc_media *)st;

	return err;
}