Example #1
0
static int encode(struct aucodec_st *st, struct mbuf *dst, struct mbuf *src)
{
	int len;

	if (!mbuf_get_left(src))
		return 0;

	if (mbuf_get_left(src) != st->fsize) {
		DEBUG_WARNING("encode: got %d bytes, expected %d\n",
			      mbuf_get_left(src), st->fsize);
		return EINVAL;
	}

	if (mbuf_get_space(dst) < MAX_PACKET) {
		int err = mbuf_resize(dst, dst->pos + MAX_PACKET);
		if (err)
			return err;
	}

	len = opus_encode(st->enc, (short *)mbuf_buf(src), st->frame_size,
			  mbuf_buf(dst), (int)mbuf_get_space(dst));
	if (len < 0) {
		DEBUG_WARNING("encode error: %d (%u bytes)\n", len,
			      mbuf_get_left(src));
		return EPROTO;
	}

	src->pos = src->end;
	dst->end = dst->pos + len;

	return 0;
}
Example #2
0
static bool udp_helper_send(int *err, struct sa *dst,
			    struct mbuf *mb, void *arg)
{
	struct menc_media *st = arg;
	unsigned int length;
	zrtp_status_t s;
	(void)dst;

	length = (unsigned int)mbuf_get_left(mb);

	s = zrtp_process_rtp(st->zrtp_stream, (char *)mbuf_buf(mb), &length);
	if (s != zrtp_status_ok) {
		warning("zrtp: zrtp_process_rtp failed (status = %d)\n", s);
		return false;
	}

	/* make sure target buffer is large enough */
	if (length > mbuf_get_space(mb)) {
		warning("zrtp: zrtp_process_rtp: length > space (%u > %u)\n",
			length, mbuf_get_space(mb));
		*err = ENOMEM;
	}

	mb->end = mb->pos + length;

	return false;
}
Example #3
0
static bool udp_helper_send(int *err, struct sa *dst,
			    struct mbuf *mb, void *arg)
{
	struct menc_media *st = arg;
	unsigned int length;
	zrtp_status_t s;
	const char *proto_name = "rtp";
	enum pkt_type ptype = get_packet_type(mb);

	if (drop_packets(st))
		return true;

	length = (unsigned int)mbuf_get_left(mb);

	/* only RTP/RTCP packets should be processed */
	if (ptype == PKT_TYPE_RTCP) {
		proto_name = "rtcp";
		s = zrtp_process_rtcp(st->zrtp_stream,
			    (char *)mbuf_buf(mb), &length);
	}
	else if (ptype == PKT_TYPE_RTP) {
		s = zrtp_process_rtp(st->zrtp_stream,
			    (char *)mbuf_buf(mb), &length);
	}
	else
		return false;

	if (s != zrtp_status_ok) {

		if (s == zrtp_status_drop)
			return true;

		warning("zrtp: send(port=%d): zrtp_process_%s failed"
			" (status = %d '%s')\n",
			sa_port(dst), proto_name, s, zrtp_log_status2str(s));
		return false;
	}

	/* make sure target buffer is large enough */
	if (length > mbuf_get_space(mb)) {
		warning("zrtp: zrtp_process_%s: length > space (%u > %u)\n",
			proto_name, length, mbuf_get_space(mb));
		*err = ENOMEM;
	}

	mb->end = mb->pos + length;

	return false;
}
Example #4
0
/* src=NULL means lost packet */
static int decode(struct aucodec_st *st, struct mbuf *dst, struct mbuf *src)
{
	int r;

	if (!mbuf_get_left(src) && !st->got_packet)
		return 0;

	/* Make sure there is enough space in the buffer */
	if (mbuf_get_space(dst) < st->fsize) {
		int err = mbuf_resize(dst, dst->pos + st->fsize);
		if (err)
			return err;
	}

	r = opus_decode(st->dec, mbuf_buf(src), (int)mbuf_get_left(src),
			(short *)mbuf_buf(dst), st->frame_size, 0);
	if (r <= 0) {
		DEBUG_WARNING("opus_decode: r=%d (%u bytes)\n",
			      r, mbuf_get_left(src));
		return EBADMSG;
	}

	if (src)
		src->pos = src->end;

	dst->end += 2 * r * aucodec_ch(st->ac);

	st->got_packet = true;

	return 0;
}
Example #5
0
static int decode_frame(struct aucodec_st *st, struct mbuf *dst,
			struct mbuf *src, uint16_t src_len)
{
	int ret, err;

	if (mbuf_get_left(src) < src_len) {
		DEBUG_WARNING("dec: corrupt frame %u < %u\n",
			      mbuf_get_left(src), src_len);
		return EPROTO;
	}

	/* Make sure there is enough space in the buffer */
	if (mbuf_get_space(dst) < st->fsize) {
		err = mbuf_resize(dst, dst->size + st->fsize);
		if (err)
			return err;
	}

	ret = celt_decode(st->dec, mbuf_buf(src), src_len,
			  (short *)mbuf_buf(dst), st->frame_size);
	if (CELT_OK != ret) {
		DEBUG_WARNING("celt_decode: ret=%d\n", ret);
	}

	DEBUG_INFO("decode: %u -> %u\n", src_len, st->fsize);

	if (src)
		mbuf_advance(src, src_len);

	dst->end += st->fsize;

	return 0;
}
Example #6
0
/**
 * Encoder audio and send via stream
 *
 * @note This function has REAL-TIME properties
 */
static void encode_rtp_send(struct audio *a, struct autx *tx,
			    int16_t *sampv, size_t sampc)
{
	size_t len;
	int err;

	if (!tx->ac)
		return;

	tx->mb->pos = tx->mb->end = STREAM_PRESZ;
	len = mbuf_get_space(tx->mb);

	err = tx->ac->ench(tx->enc, mbuf_buf(tx->mb), &len, sampv, sampc);
	if (err) {
		DEBUG_WARNING("%s encode error: %d samples (%m)\n",
			      tx->ac->name, sampc, err);
		goto out;
	}

	tx->mb->pos = STREAM_PRESZ;
	tx->mb->end = STREAM_PRESZ + len;

	if (mbuf_get_left(tx->mb)) {

		err = stream_send(a->strm, tx->marker, -1, tx->ts, tx->mb);
		if (err)
			goto out;
	}

	tx->ts += (uint32_t)(tx->is_g722 ? sampc/2 : sampc);

 out:
	tx->marker = false;
}
Example #7
0
/* PLC is only valid for Decoding (RX) */
static int dec(struct aufilt_st *st, struct mbuf *mb)
{
	int nsamp = (int)mbuf_get_left(mb) / 2;

	if (nsamp) {
		nsamp = plc_rx(&st->plc, (int16_t *)mbuf_buf(mb), nsamp);
		if (nsamp >= 0)
			mb->end = mb->pos + (2*nsamp);
	}
	else {
		nsamp = (int)st->psize / 2;

		re_printf("plc: concealing %u bytes\n", st->psize);

		if (mbuf_get_space(mb) < st->psize) {

			int err = mbuf_resize(mb, st->psize);
			if (err)
				return err;
		}

		nsamp = plc_fillin(&st->plc, (int16_t *)mbuf_buf(mb), nsamp);

		mb->end = mb->pos + 2 * nsamp;
	}

	return 0;
}
Example #8
0
static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
{
	struct dtls_flow *flow = arg;
	uint8_t b;
	int r, n;

	if (mbuf_get_left(mb) < 1)
		return false;

	/* ignore non-DTLS packets */
	b = mb->buf[mb->pos];
	if (b < 20 || b > 63)
		return false;

	if (!sa_cmp(src, &flow->peer, SA_ALL))
		return false;

	/* feed SSL data to the BIO */
	r = BIO_write(flow->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb));
	if (r <= 0)
		return true;

	n = SSL_read(flow->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb));
	if (n <= 0) {
		ERR_clear_error();
	}

	if (!flow->up && SSL_state(flow->ssl) == SSL_ST_OK) {

		struct key client_key, server_key;
		char profile[256];
		int err;

		flow->up = true;

		err = get_srtp_key_info(flow, profile, sizeof(profile),
					&client_key, &server_key);
		if (err) {
			warning("dtls: SRTP key info: %m\n", err);
			return true;
		}

		flow->estabh(0, flow, profile,
			     &client_key, &server_key, flow->arg);
	}

	return true;
}
Example #9
0
static void read_handler(int flags, void *arg)
{
	struct ausrc_st *st = arg;
	struct mbuf *mb = st->mb;
	int n;
	(void)flags;

	n = read(st->fd, mbuf_buf(mb), mbuf_get_space(mb));
	if (n <= 0)
		return;

	mb->pos += n;

	if (mb->pos < mb->size)
		return;

	st->rh(mb->buf, mb->size, st->arg);

	mb->pos = 0;
}
Example #10
0
/**
 * Encoder audio and send via stream
 *
 * @note This function has REAL-TIME properties
 *
 * @param a     Audio object
 * @param tx    Audio transmit object
 * @param sampv Audio samples
 * @param sampc Number of audio samples
 */
static void encode_rtp_send(struct audio *a, struct autx *tx,
			    int16_t *sampv, size_t sampc)
{
	size_t frame_size;  /* number of samples per channel */
	size_t len;
	int err;

	if (!tx->ac)
		return;

	tx->mb->pos = tx->mb->end = STREAM_PRESZ;
	len = mbuf_get_space(tx->mb);

	err = tx->ac->ench(tx->enc, mbuf_buf(tx->mb), &len, sampv, sampc);
	if (err) {
		warning("audio: %s encode error: %d samples (%m)\n",
			tx->ac->name, sampc, err);
		goto out;
	}

	tx->mb->pos = STREAM_PRESZ;
	tx->mb->end = STREAM_PRESZ + len;

	if (mbuf_get_left(tx->mb)) {

		err = stream_send(a->strm, tx->marker, -1, tx->ts, tx->mb);
		if (err)
			goto out;
	}

	/* The RTP clock rate used for generating the RTP timestamp is
	 * independent of the number of channels and the encoding
	 */
	frame_size = (tx->is_g722 ? sampc/2 : sampc) / tx->ac->ch;

	tx->ts += (uint32_t)frame_size;

 out:
	tx->marker = false;
}
Example #11
0
static bool send_handler(int *err, struct sa *dst, struct mbuf *mb, void *arg)
{
	struct menc_st *st = arg;
	err_status_t e;
	int len;
	(void)dst;

	if (!st->use_srtp || !is_rtp_or_rtcp(mb))
		return false;

	len = (int)mbuf_get_left(mb);

	if (mbuf_get_space(mb) < ((size_t)len + SRTP_MAX_TRAILER_LEN)) {
		mbuf_resize(mb, mb->pos + len + SRTP_MAX_TRAILER_LEN);
	}

	if (is_rtcp_packet(mb)) {
		e = srtp_protect_rtcp(st->srtp_tx, mbuf_buf(mb), &len);
	}
	else {
		e = srtp_protect(st->srtp_tx, mbuf_buf(mb), &len);
	}

	if (err_status_ok != e) {
		DEBUG_WARNING("send: failed to protect %s-packet"
			      " with %d bytes (%H)\n",
			      is_rtcp_packet(mb) ? "RTCP" : "RTP",
			      len, errstatus_print, e);
		*err = EPROTO;
		return false;
	}

	mbuf_set_end(mb, mb->pos + len);

	return false;  /* continue processing */
}
Example #12
0
static bool recv_handler(int *err, struct mbuf *mb, bool *estab, void *arg)
{
	struct tls_conn *tc = arg;
	int r;

	/* feed SSL data to the BIO */
	r = BIO_write(tc->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb));
	if (r <= 0) {
		DEBUG_WARNING("recv: BIO_write %d\n", r);
		*err = ENOMEM;
		return true;
	}

	if (SSL_state(tc->ssl) != SSL_ST_OK) {

		if (tc->up) {
			*err = EPROTO;
			return true;
		}

		if (tc->active) {
			*err = tls_connect(tc);
		}
		else {
			*err = tls_accept(tc);
		}

		DEBUG_INFO("state=0x%04x\n", SSL_state(tc->ssl));

		/* TLS connection is established */
		if (SSL_state(tc->ssl) != SSL_ST_OK)
			return true;

		*estab = true;
		tc->up = true;
	}

	mbuf_set_pos(mb, 0);

	for (;;) {
		int n;

		if (mbuf_get_space(mb) < 4096) {
			*err = mbuf_resize(mb, mb->size + 8192);
			if (*err)
				return true;
		}

		n = SSL_read(tc->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb));
		if (n < 0) {
			const int ssl_err = SSL_get_error(tc->ssl, n);

			switch (ssl_err) {

			case SSL_ERROR_WANT_READ:
				break;

			default:
				*err = EPROTO;
				return true;
			}

			break;
		}
		else if (n == 0)
			break;

		mb->pos += n;
	}

	mbuf_set_end(mb, mb->pos);
	mbuf_set_pos(mb, 0);

	return false;
}
Example #13
0
static bool recv_handler(struct sa *src, struct mbuf *mb, void *arg)
{
	struct tls_sock *ts = arg;
	struct tls_conn *tc;
	int r;

	tc = tls_udp_conn(ts, src);
	if (!tc) {

		/* No connection found, assuming Server role */

		tc = conn_alloc(ts, src);
		if (!tc)
			return true;

		SSL_set_verify(tc->ssl, 0, 0);
		SSL_set_accept_state(tc->ssl);
	}

	/* feed SSL data to the BIO */
	r = BIO_write(tc->sbio_in, mbuf_buf(mb), (int)mbuf_get_left(mb));
	if (r <= 0)
		return true;

	check_timer(tc);

	mbuf_set_pos(mb, 0);

	for (;;) {
		int n;

		if (mbuf_get_space(mb) < 4096) {
			if (mbuf_resize(mb, mb->size + 8192))
				return true;
		}

		n = SSL_read(tc->ssl, mbuf_buf(mb), (int)mbuf_get_space(mb));
		if (n < 0) {
			const int ssl_err = SSL_get_error(tc->ssl, n);

			switch (ssl_err) {

			case SSL_ERROR_WANT_READ:
				break;

			default:
				return true;
			}

			break;
		}
		else if (n == 0)
			break;

		mb->pos += n;
	}

	if (!mb->pos)
		return true;

	mbuf_set_end(mb, mb->pos);
	mbuf_set_pos(mb, 0);

	return false;
}