예제 #1
0
int stream_send(struct stream *s, bool marker, int pt, uint32_t ts,
		struct mbuf *mb)
{
	int err = 0;

	if (!s)
		return EINVAL;

	if (!sa_isset(sdp_media_raddr(s->sdp), SA_ALL))
		return 0;
	if (sdp_media_dir(s->sdp) != SDP_SENDRECV)
		return 0;

	metric_add_packet(&s->metric_tx, mbuf_get_left(mb));

	if (pt < 0)
		pt = s->pt_enc;

	if (pt >= 0) {
		err = rtp_send(s->rtp, sdp_media_raddr(s->sdp),
			       marker, pt, ts, mb);
		if (err)
			s->metric_tx.n_err++;
	}

	rtpkeep_refresh(s->rtpkeep, ts);

	return err;
}
예제 #2
0
int stream_send(struct stream *s, bool marker, int pt, uint32_t ts,
		struct mbuf *mb)
{
	int err = 0;

	if (!s)
		return EINVAL;

	if (!sa_isset(sdp_media_raddr(s->sdp), SA_ALL))
		return 0;
	if (sdp_media_dir(s->sdp) != SDP_SENDRECV)
		return 0;

	s->stats.b_tx += mbuf_get_left(mb);

	if (pt < 0)
		pt = s->pt_enc;

	if (pt >= 0) {
		err = rtp_send(s->rtp, sdp_media_raddr(s->sdp),
			       marker, pt, ts, mb);
	}

	rtpkeep_refresh(s->rtpkeep, ts);

	++s->stats.n_tx;

	return err;
}
예제 #3
0
파일: zrtp.c 프로젝트: czarkoff/baresip
static int media_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_media *st;
	zrtp_status_t s;
	int layer = 10; /* above zero */
	int err = 0;
	(void)rtcpsock;

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

	st = *stp;
	if (st)
		goto start;

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

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

	err = udp_register_helper(&st->uh, rtpsock, layer,
				  udp_helper_send, udp_helper_recv, st);
	if (err)
		goto out;

	s = zrtp_stream_attach(sess->zrtp_session, &st->zrtp_stream);
	if (s != zrtp_status_ok) {
		warning("zrtp: zrtp_stream_attach failed (status=%d)\n", s);
		err = EPROTO;
		goto out;
	}

	zrtp_stream_set_userdata(st->zrtp_stream, st);

 out:
	if (err) {
		mem_deref(st);
		return err;
	}
	else
		*stp = st;

 start:
	if (sa_isset(sdp_media_raddr(sdpm), SA_ALL)) {
		st->raddr = *sdp_media_raddr(sdpm);

		s = zrtp_stream_start(st->zrtp_stream, rtp_sess_ssrc(rtp));
		if (s != zrtp_status_ok) {
			warning("zrtp: zrtp_stream_start: status = %d\n", s);
		}
	}

	return err;
}
예제 #4
0
파일: bfcp.c 프로젝트: AmesianX/baresip
int bfcp_start(struct bfcp *bfcp)
{
	const struct sa *paddr;
	uint32_t confid = 0;
	uint16_t userid = 0;
	int err = 0;

	if (!bfcp)
		return EINVAL;

	if (!sdp_media_rport(bfcp->sdpm)) {
		info("bfcp channel is disabled\n");
		return 0;
	}

	if (bfcp->active) {

		paddr  = sdp_media_raddr(bfcp->sdpm);
		confid = sdp_media_rattr_u32(bfcp->sdpm, "confid");
		userid = sdp_media_rattr_u32(bfcp->sdpm, "userid");

		err = bfcp_request(bfcp->conn, paddr, BFCP_VER2, BFCP_HELLO,
				   confid, userid, bfcp_resp_handler, bfcp, 0);
	}

	return err;
}
예제 #5
0
static int update(struct mnat_sess *sess)
{
	struct le *le;
	int err = 0;

	if (!sess)
		return EINVAL;

	for (le=sess->medial.head; le; le=le->next) {

		struct mnat_media *m = le->data;
		struct sa raddr1, raddr2;

		raddr1 = *sdp_media_raddr(m->sdpm);
		sdp_media_raddr_rtcp(m->sdpm, &raddr2);

		if (m->turnc1 && sa_isset(&raddr1, SA_ALL))
			err |= turnc_add_chan(m->turnc1, &raddr1, NULL, NULL);

		if (m->turnc2 && sa_isset(&raddr2, SA_ALL))
			err |= turnc_add_chan(m->turnc2, &raddr2, NULL, NULL);
	}

	return err;
}
예제 #6
0
파일: audio.c 프로젝트: quentusrex/baresip
/*
 * Reference:
 *
 * https://www.avm.de/de/Extern/files/x-rtp/xrtpv32.pdf
 */
int audio_print_rtpstat(struct re_printf *pf, const struct audio *a)
{
	const struct stream *s;
	const struct rtcp_stats *rtcp;
	int srate_tx = 8000;
	int srate_rx = 8000;
	int err;

	if (!a)
		return 1;

	s = a->strm;
	rtcp = &s->rtcp_stats;

	if (!rtcp->tx.sent)
		return 1;

	if (a->tx.ac)
		srate_tx = get_srate(a->tx.ac);
	if (a->rx.ac)
		srate_rx = get_srate(a->rx.ac);

	err = re_hprintf(pf,
			 "EX=BareSip;"   /* Reporter Identifier	             */
			 "CS=%d;"        /* Call Setup in milliseconds       */
			 "CD=%d;"        /* Call Duration in seconds	     */
			 "PR=%u;PS=%u;"  /* Packets RX, TX                   */
			 "PL=%d,%d;"     /* Packets Lost RX, TX              */
			 "PD=%d,%d;"     /* Packets Discarded, RX, TX        */
			 "JI=%.1f,%.1f;" /* Jitter RX, TX in timestamp units */
			 "IP=%J,%J"      /* Local, Remote IPs                */
			 ,
			 call_setup_duration(s->call) * 1000,
			 call_duration(s->call),

			 s->metric_rx.n_packets,
			 s->metric_tx.n_packets,

			 rtcp->rx.lost, rtcp->tx.lost,

			 s->metric_rx.n_err, s->metric_tx.n_err,

			 /* timestamp units (ie: 8 ts units = 1 ms @ 8KHZ) */
			 1.0 * rtcp->rx.jit/1000 * (srate_rx/1000),
			 1.0 * rtcp->tx.jit/1000 * (srate_tx/1000),

			 sdp_media_laddr(s->sdp),
			 sdp_media_raddr(s->sdp)
			 );

	if (a->tx.ac) {
		err |= re_hprintf(pf, ";EN=%s/%d", a->tx.ac->name, srate_tx );
	}
	if (a->rx.ac) {
		err |= re_hprintf(pf, ";DE=%s/%d", a->rx.ac->name, srate_rx );
	}

	return err;
}
예제 #7
0
파일: sip_ua.c 프로젝트: chk-jxcn/redemo
/* print SDP status */
static void update_media(void)
{
	const struct sdp_format *fmt;

	re_printf("SDP peer address: %J\n", sdp_media_raddr(sdp_media));

	fmt = sdp_media_rformat(sdp_media, NULL);
	if (!fmt) {
		re_printf("no common media format found\n");
		return;
	}

	re_printf("SDP media format: %s/%u/%u (payload type: %u)\n",
		  fmt->name, fmt->srate, fmt->ch, fmt->pt);
}
예제 #8
0
int stream_debug(struct re_printf *pf, const struct stream *s)
{
	struct sa rrtcp;
	int err;

	if (!s)
		return 0;

	err  = re_hprintf(pf, " %s dir=%s pt_enc=%d\n", sdp_media_name(s->sdp),
			  sdp_dir_name(sdp_media_dir(s->sdp)),
			  s->pt_enc);

	sdp_media_raddr_rtcp(s->sdp, &rrtcp);
	err |= re_hprintf(pf, " remote: %J/%J\n",
			  sdp_media_raddr(s->sdp), &rrtcp);

	err |= rtp_debug(pf, s->rtp);
	err |= jbuf_debug(pf, s->jbuf);

	return err;
}
예제 #9
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);
}
예제 #10
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);
}
예제 #11
0
파일: call.c 프로젝트: sealaunch/baresip
int call_accept(struct call *call, struct sipsess_sock *sess_sock,
		const struct sip_msg *msg)
{
	bool got_offer;
	int err;

	if (!call || !msg)
		return EINVAL;

	call->outgoing = false;

	got_offer = (mbuf_get_left(msg->mb) > 0);

	err = pl_strdup(&call->peer_uri, &msg->from.auri);
	if (err)
		return err;

	if (pl_isset(&msg->from.dname)) {
		err = pl_strdup(&call->peer_name, &msg->from.dname);
		if (err)
			return err;
	}

	if (got_offer) {
		struct sdp_media *m;
		const struct sa *raddr;

		err = sdp_decode(call->sdp, msg->mb, true);
		if (err)
			return err;

		call->got_offer = true;

		/*
		 * Each media description in the SDP answer MUST
		 * use the same network type as the corresponding
		 * media description in the offer.
		 *
		 * See RFC 6157
		 */
		m = stream_sdpmedia(audio_strm(call->audio));
		raddr = sdp_media_raddr(m);

		if (sa_af(raddr) != call->af) {
			info("call: incompatible address-family"
			     " (local=%s, remote=%s)\n",
			     net_af2name(call->af),
			     net_af2name(sa_af(raddr)));

			sip_treply(NULL, uag_sip(), msg,
				   488, "Not Acceptable Here");

			call_event_handler(call, CALL_EVENT_CLOSED,
					   "Wrong address family");
			return 0;
		}

		/* Check if we have any common audio codecs, after
		 * the SDP offer has been parsed
		 */
		if (!have_common_audio_codecs(call)) {
			info("call: no common audio codecs - rejected\n");

			sip_treply(NULL, uag_sip(), msg,
				   488, "Not Acceptable Here");

			call_event_handler(call, CALL_EVENT_CLOSED,
					   "No audio codecs");

			return 0;
		}
	}

	err = sipsess_accept(&call->sess, sess_sock, msg, 180, "Ringing",
			     ua_cuser(call->ua), "application/sdp", NULL,
			     auth_handler, call->acc, true,
			     sipsess_offer_handler, sipsess_answer_handler,
			     sipsess_estab_handler, sipsess_info_handler,
			     sipsess_refer_handler, sipsess_close_handler,
			     call, "Allow: %s\r\n", uag_allowed_methods());
	if (err) {
		warning("call: sipsess_accept: %m\n", err);
		return err;
	}

	set_state(call, STATE_INCOMING);

	/* New call */
	tmr_start(&call->tmr_inv, LOCAL_TIMEOUT*1000, invite_timeout, call);

	if (!call->acc->mnat)
		call_event_handler(call, CALL_EVENT_INCOMING, call->peer_uri);

	return err;
}
예제 #12
0
int test_sdp_all(void)
{
	struct sdp_session *sess = NULL;
	struct sdp_media *audio = NULL;
	struct mbuf *desc = NULL;
	struct sa ref;
	const struct sdp_format *rc = NULL, *sc;
	struct sa laddr;
	int err;

	(void)sa_set_str(&laddr, ref_host, 0);

	err = sdp_session_alloc(&sess, &laddr);
	if (err)
		goto out;

	err = sdp_media_add(&audio, sess, sdp_media_audio, 5004,
			    sdp_proto_rtpavp);
	if (err)
		goto out;

	err  = sdp_format_add(NULL, audio, false, ref_pt, ref_cname,
			      ref_srate, 1, NULL, NULL, NULL, false, NULL);
	err |= sdp_format_add(NULL, audio, false, "110", cname_speex,
			      16000, 2, NULL, NULL, NULL, false, NULL);
	if (err)
		goto out;

	/* find codec - expected */
	sc = sdp_media_format(audio, true, NULL, 0, "PCMU", 8000, 1);
	if (!sc) {
		DEBUG_WARNING("codec not found\n");
		err = ENOENT;
		goto out;
	}

	sc = sdp_media_format(audio, true, NULL, 110, "Speex", 16000, 2);
	if (!sc) {
		DEBUG_WARNING("codec not found: speex\n");
		err = ENOENT;
		goto out;
	}

	/* find codec - not expected */
	sc = sdp_media_format(audio, true, NULL, -1, "Speex", 8000, 1);
	if (sc) {
		DEBUG_WARNING("unexpected codec found\n");
		err = EINVAL;
		goto out;
	}

	err = sdp_encode(&desc, sess, true);
	if (err)
		goto out;

	if (!sdp_cmp(desc, ref_msg)) {
		DEBUG_WARNING("ref: %s\n", ref_msg);
		DEBUG_WARNING("sdp: %b\n", desc->buf, desc->end);
		err = EBADMSG;
		goto out;
	}

	err = sdp_decode(sess, desc, false);
	if (err)
		goto out;

	rc = sdp_media_rformat(audio, NULL);
	if (!rc) {
		err = ENOENT;
		goto out;
	}

	err = sa_set_str(&ref, ref_host, ref_port);
	if (err)
		goto out;

	err = EINVAL;

	if (!sa_cmp(sdp_media_raddr(audio), &ref, SA_ALL))
		goto out;

	if (!rc)
		goto out;

	if (0 != strcmp(rc->id, ref_pt))
		goto out;

	if (0 != strcmp(ref_cname, rc->name))
		goto out;

	if (rc->srate != ref_srate)
		goto out;

	err = 0;

 out:
	mem_deref(audio);
	mem_deref(sess);
	mem_deref(desc);

	return err;
}