/* (C) 2011-2021 by Harald Welte <laforge@gnumonks.org>
 * (C) 2011 by On-Waves e.h.f
 * All Rights Reserved
 *
 * SPDX-License-Identifier: GPL-2.0+
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */

/*! \file osmo_ortp.c
 *  \brief Integration of libortp into osmocom framework (select, logging)
 */

#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>
#include <netdb.h>

#include <osmocom/core/logging.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/select.h>
#include <osmocom/core/socket.h>
#include <osmocom/trau/osmo_ortp.h>

#include <ortp/ortp.h>
#include <ortp/rtp.h>
#include <ortp/port.h>
#include <ortp/rtpsession.h>

#include "config.h"

static PayloadType *payload_type_efr;
static PayloadType *payload_type_hr;
static RtpProfile *osmo_pt_profile;

static void *tall_rtp_ctx;

/* malloc integration */

static void *osmo_ortp_malloc(size_t sz)
{
	return talloc_size(tall_rtp_ctx, sz);
}

static void *osmo_ortp_realloc(void *ptr, size_t sz)
{
	return talloc_realloc_size(tall_rtp_ctx, ptr, sz);
}

static void osmo_ortp_free(void *ptr)
{
	talloc_free(ptr);
}

static OrtpMemoryFunctions osmo_ortp_memfn = {
	.malloc_fun = osmo_ortp_malloc,
	.realloc_fun = osmo_ortp_realloc,
	.free_fun = osmo_ortp_free
};

/* logging */

struct level_map {
	OrtpLogLevel ortp;
	int osmo_level;
};
static const struct level_map level_map[] = {
	{ ORTP_DEBUG,	LOGL_DEBUG },
	{ ORTP_MESSAGE, LOGL_INFO },
	{ ORTP_WARNING, LOGL_NOTICE },
	{ ORTP_ERROR,	LOGL_ERROR },
	{ ORTP_FATAL,	LOGL_FATAL },
};
static int ortp_to_osmo_lvl(OrtpLogLevel lev)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(level_map); i++) {
		if (level_map[i].ortp == lev)
			return level_map[i].osmo_level;
	}
	/* default */
	return LOGL_ERROR;
}

static void my_ortp_logfn(
#if HAVE_ORTP_LOG_DOMAIN
	const char *domain,
#endif
	OrtpLogLevel lev, const char *fmt, va_list args)
{
	/* Some strings coming from ortp are not endline terminated and mangle
	 * the output. Make sure all strings are endl terminated before
	 * printing.
	 */
	int needs_endl;
	const char *domain_str;
	char *str;
	size_t fmt_len = strlen(fmt);
#if HAVE_ORTP_LOG_DOMAIN
	/* domain can be NULL, found experimentally */
	domain_str = domain ? : "";
#else
	domain_str = "";
#endif
	size_t  domain_len = strlen(domain_str);

	if (fmt_len == 0)
		return;

	needs_endl = fmt[fmt_len - 1] != '\n' ? 1 : 0;

	str = osmo_ortp_malloc(domain_len + 2 /*": "*/ + fmt_len + needs_endl + 1);
	sprintf(str, "%s%s%s%s", domain_str, domain_len ? ": " : "", fmt, needs_endl ? "\n" : "");

	osmo_vlogp(DLMIB, ortp_to_osmo_lvl(lev), __FILE__, 0,
		   0, str, args);

	osmo_ortp_free(str);

}

/* ORTP signal callbacks */

static void ortp_sig_cb_ssrc(RtpSession *rs, void *data)
{
	int port = rtp_session_get_local_port(rs);
	uint32_t ssrc = rtp_session_get_recv_ssrc(rs);

	LOGP(DLMIB, LOGL_INFO,
	     "osmo-ortp(%d): ssrc_changed to 0x%08x, resetting\n", port, ssrc);
	rtp_session_reset(rs);
}

static void ortp_sig_cb_pt(RtpSession *rs, void *data)
{
	int port = rtp_session_get_local_port(rs);
	int pt = rtp_session_get_recv_payload_type(rs);

	LOGP(DLMIB, LOGL_NOTICE,
	     "osmo-ortp(%d): payload_type_changed to 0x%02x\n", port, pt);
}

static void ortp_sig_cb_net(RtpSession *rs, void *data)
{
	int port = rtp_session_get_local_port(rs);

	LOGP(DLMIB, LOGL_ERROR,
	     "osmo-ortp(%d): network_error %s\n", port, (char *)data);
}

static void ortp_sig_cb_ts(RtpSession *rs, void *data)
{
	int port = rtp_session_get_local_port(rs);
	uint32_t ts = rtp_session_get_current_recv_ts(rs);

	LOGP(DLMIB, LOGL_NOTICE,
	     "osmo-ortp(%d): timestamp_jump, new TS %d, resyncing\n", port, ts);
	rtp_session_resync(rs);
}

static inline bool recv_with_cb(struct osmo_rtp_socket *rs)
{
	uint8_t *payload;
	mblk_t *mblk = rtp_session_recvm_with_ts(rs->sess, rs->rx_user_ts);
	if (!mblk)
		return false;

	int plen = rtp_get_payload(mblk, &payload);
	/* hand into receiver */
	if (rs->rx_cb && plen > 0)
		rs->rx_cb(rs, payload, plen, rtp_get_seqnumber(mblk),
			  rtp_get_timestamp(mblk), rtp_get_markbit(mblk));
	freemsg(mblk);
	if (plen > 0)
		return true;
	return false;
}

/*! \brief poll the socket for incoming data
 *  \param[in] rs the socket to be polled
 *  \returns number of packets received + handed to the rx_cb
 */
int osmo_rtp_socket_poll(struct osmo_rtp_socket *rs)
{
	if (rs->flags & OSMO_RTP_F_DISABLED)
		return 0;

	if (recv_with_cb(rs))
		return 1;

	/* this happens every time we miss an incoming RTP frame, which is quite common
	 * when a voice channel is first activated, or also in case of packet loss.
	 * See also https://osmocom.org/issues/4464 */
	LOGP(DLMIB, LOGL_DEBUG, "osmo_rtp_socket_poll(%u): No message received\n", rs->rx_user_ts);
	return 0;
}

/* Osmo FD callbacks */

static int osmo_rtp_fd_cb(struct osmo_fd *fd, unsigned int what)
{
	struct osmo_rtp_socket *rs = fd->data;

	if (what & OSMO_FD_READ) {
		/* in polling mode, we don't want to be called here */
		if (rs->flags & OSMO_RTP_F_POLL) {
			osmo_fd_read_disable(fd);
			return 0;
		}
		if (!recv_with_cb(rs))
			LOGP(DLMIB, LOGL_INFO, "recvm_with_ts(%u): ERROR!\n",
			     rs->rx_user_ts);
		rs->rx_user_ts += 160;
	}
	/* writing is not queued at the moment, so OSMO_FD_WRITE
	 * shouldn't occur */
	return 0;
}

/* Internal API coming from rtpsession_priv.h, used in osmo_rtcp_fd_cb */
#pragma message ("Using internal ortp API: rtp_session_rtcp_rec")
int rtp_session_rtcp_recv(RtpSession * session);

static int osmo_rtcp_fd_cb(struct osmo_fd *fd, unsigned int what)
{
	struct osmo_rtp_socket *rs = fd->data;

	/* We probably don't need this at all, as
	 * rtp_session_recvm_with_ts() will alway also poll the RTCP
	 * file descriptor for new data */
	return rtp_session_rtcp_recv(rs->sess);
}

static int osmo_rtp_socket_fdreg(struct osmo_rtp_socket *rs)
{
	int rc;

	osmo_fd_setup(&rs->rtp_bfd, rtp_session_get_rtp_socket(rs->sess), OSMO_FD_READ, osmo_rtp_fd_cb, rs, 0);
	osmo_fd_setup(&rs->rtcp_bfd, rtp_session_get_rtcp_socket(rs->sess), OSMO_FD_READ, osmo_rtcp_fd_cb, rs, 0);

	rc = osmo_fd_register(&rs->rtp_bfd);
	if (rc < 0)
		return rc;

	rc = osmo_fd_register(&rs->rtcp_bfd);
	if (rc < 0) {
		osmo_fd_unregister(&rs->rtp_bfd);
		return rc;
	}

	return 0;
}

static void create_payload_types()
{
	PayloadType *pt;

	/* EFR */
	pt = payload_type_new();
	pt->type = PAYLOAD_AUDIO_PACKETIZED;
	pt->clock_rate = 8000;
	pt->mime_type = "EFR";
	pt->normal_bitrate = 12200;
	pt->channels = 1;
	payload_type_efr = pt;

	/* HR */
	pt = payload_type_new();
	pt->type = PAYLOAD_AUDIO_PACKETIZED;
	pt->clock_rate = 8000;
	pt->mime_type = "HR";
	pt->normal_bitrate = 6750; /* FIXME */
	pt->channels = 1;
	payload_type_hr = pt;

	/* create a new RTP profile as clone of AV profile */
	osmo_pt_profile = rtp_profile_clone(&av_profile);

	/* add the GSM specific payload types. They are all dynamically
	 * assigned, but in the Osmocom GSM system we have allocated
	 * them as follows: */
	rtp_profile_set_payload(osmo_pt_profile, RTP_PT_GSM_EFR, payload_type_efr);
	rtp_profile_set_payload(osmo_pt_profile, RTP_PT_GSM_HALF, payload_type_hr);
	rtp_profile_set_payload(osmo_pt_profile, RTP_PT_AMR, &payload_type_amr);
}

/* public functions */

/*! \brief initialize Osmocom RTP code
 *  \param[in] ctx default talloc context for library-internal allocations
 */
void osmo_rtp_init(void *ctx)
{
	tall_rtp_ctx = ctx;
	ortp_set_memory_functions(&osmo_ortp_memfn);
	ortp_init();
	ortp_set_log_level_mask(
#if HAVE_ORTP_LOG_DOMAIN
		ORTP_LOG_DOMAIN,
#endif
		0xffff);

	ortp_set_log_handler(my_ortp_logfn);
	create_payload_types();
}

/*! \brief Set Osmocom RTP socket parameters
 *  \param[in] rs OsmoRTP socket
 *  \param[in] param defined which parameter to set
                     OSMO_RTP_P_JITBUF - enables regular jitter buffering
                     OSMO_RTP_P_JIT_ADAP - enables adaptive jitter buffering
 *  \param[in] val Size of jitter buffer (in ms), 0 means disable buffering
 *  \returns negative value on error, 0 or 1 otherwise
                      (depending on whether given jitter buffering is enabled)
 */
int osmo_rtp_socket_set_param(struct osmo_rtp_socket *rs,
			      enum osmo_rtp_param param, int val)
{
	switch (param) {
	case OSMO_RTP_P_JIT_ADAP:
		rtp_session_enable_adaptive_jitter_compensation(rs->sess,
								(bool)val);
		/* fall-through on-purpose - we have to set val anyway */
	case OSMO_RTP_P_JITBUF:
		rtp_session_enable_jitter_buffer(rs->sess,
			(val) ? TRUE : FALSE);
		if (val)
			rtp_session_set_jitter_compensation(rs->sess, val);
		break;
	default:
		return -EINVAL;
	}
	if (param == OSMO_RTP_P_JIT_ADAP)
		return rtp_session_adaptive_jitter_compensation_enabled(rs->sess);
	return rtp_session_jitter_buffer_enabled(rs->sess);
}

/*! \brief Create a new RTP socket
 *  \param[in] talloc_cxt talloc context for this allocation. NULL for
 *  			  dafault context
 *  \param[in] flags Flags like OSMO_RTP_F_POLL
 *  \returns pointer to library-allocated \a struct osmo_rtp_socket
 */
struct osmo_rtp_socket *osmo_rtp_socket_create(void *talloc_ctx, unsigned int flags)
{
	struct osmo_rtp_socket *rs;

	if (!talloc_ctx)
		talloc_ctx = tall_rtp_ctx;

	rs = talloc_zero(talloc_ctx, struct osmo_rtp_socket);
	if (!rs)
		return NULL;

	rs->flags = OSMO_RTP_F_DISABLED | flags;
	rs->sess = rtp_session_new(RTP_SESSION_SENDRECV);
	if (!rs->sess) {
		talloc_free(rs);
		return NULL;
	}
	rtp_session_set_data(rs->sess, rs);
	rtp_session_set_profile(rs->sess, osmo_pt_profile);
	rtp_session_set_jitter_compensation(rs->sess, 100);

	/* ortp >= 0.24.0 doesn't differentiate between SO_REUSEADDR and
	 * SO_REUSEPORT, and has both enabled by default.  The latter means that
	 * we can end up with non-unique port bindings as we will not fail to
	 * bind the same port twice */
	rtp_session_set_reuseaddr(rs->sess, false);

	rtp_session_signal_connect(rs->sess, "ssrc_changed",
				   (RtpCallback) ortp_sig_cb_ssrc,
				   RTP_SIGNAL_PTR_CAST(rs));

	rtp_session_signal_connect(rs->sess, "payload_type_changed",
				   (RtpCallback) ortp_sig_cb_pt,
				   RTP_SIGNAL_PTR_CAST(rs));

	rtp_session_signal_connect(rs->sess, "network_error",
				   (RtpCallback) ortp_sig_cb_net,
				   RTP_SIGNAL_PTR_CAST(rs));

	rtp_session_signal_connect(rs->sess, "timestamp_jump",
				   (RtpCallback) ortp_sig_cb_ts,
				   RTP_SIGNAL_PTR_CAST(rs));

	/* initialize according to the RFC */
	rtp_session_set_seq_number(rs->sess, random());
	rs->tx_timestamp = random();

	/* Make sure ssrc changes are detected immediately */
	rtp_session_set_ssrc_changed_threshold(rs->sess, 0);

	return rs;
}

/*! \brief bind a RTP socket to a local port
 *  \param[in] rs OsmoRTP socket
 *  \param[in] ip hostname/ip as string
 *  \param[in] port UDP port number, -1 for random selection
 *  \returns 0 on success, <0 on error
 */
int osmo_rtp_socket_bind(struct osmo_rtp_socket *rs, const char *ip, int port)
{
	int rc, rtcp = (-1 != port) ? port + 1 : -1;
	rc = rtp_session_set_local_addr(rs->sess, ip, port, rtcp);

	if (rc < 0)
		return rc;

	rs->rtp_bfd.fd = rtp_session_get_rtp_socket(rs->sess);
	rs->rtcp_bfd.fd = rtp_session_get_rtcp_socket(rs->sess);

	return 0;
}

/*! \brief connect a OsmoRTP socket to a remote port
 *  \param[in] rs OsmoRTP socket
 *  \param[in] ip String representation of remote hostname or IP address
 *  \param[in] port UDP port number to connect to
 *
 *  If the OsmoRTP socket is not in POLL mode, this function will also
 *  cause the RTP and RTCP file descriptors to be registred with the
 *  libosmocore select() loop integration.
 *
 *  \returns 0 on success, <0 in case of error
 */
int osmo_rtp_socket_connect(struct osmo_rtp_socket *rs, const char *ip, uint16_t port)
{
	int rc;
	if (!port) {
		LOGP(DLMIB, LOGL_INFO, "osmo_rtp_socket_connect() refused to "
		     "set remote %s:%u\n", ip, port);
		return 0;
	}

	/* We don't want the connected mode enabled during
	 * rtp_session_set_remote_addr(), because that will already setup a
	 * connection and updating the remote address will no longer have an
	 * effect. Contrary to what one may expect, this must be 0 at first,
	 * and we're setting to 1 further down to establish a connection once
	 * the first RTP packet is received (OS#1661). */
	rtp_session_set_connected_mode(rs->sess, 0);

	rc = rtp_session_set_remote_addr(rs->sess, ip, port);
	if (rc < 0)
		return rc;

	/* enable the use of connect() so later getsockname() will
	 * actually return the IP address that was chosen for the local
	 * sid of the connection */
	rtp_session_set_connected_mode(rs->sess, 1);
	rs->flags &= ~OSMO_RTP_F_DISABLED;

	if (rs->flags & OSMO_RTP_F_POLL)
		return rc;
	else
		return osmo_rtp_socket_fdreg(rs);
}

/*! \brief Automatically associates a RTP socket with the first incoming UDP packet
 *  \param[in] rs OsmoRTP socket
 *
 * The bound RTP socket will wait for incoming RTP packets and as soon as it
 * sees one, will 'connect' to it, so all replies will go to that sources and
 * incoming messages from other sources will be discarded. This obviously only
 * works once.
 *
 *  \returns 0 on success, <0 in case of error.
 */
int osmo_rtp_socket_autoconnect(struct osmo_rtp_socket *rs)
{
	rtp_session_set_symmetric_rtp(rs->sess, 1);
	rtp_session_set_connected_mode(rs->sess, 1);
	rs->flags &= ~OSMO_RTP_F_DISABLED;

	if (rs->flags & OSMO_RTP_F_POLL)
		return 0;
	else
		return osmo_rtp_socket_fdreg(rs);
}

/*! \brief Increment timestamp on a RTP socket without sending any packet
 *  \param[in] rs OsmoRTP socket
 *  \param[in] duration duration in number of RTP clock ticks
 *
 * Useful to keep the RTP internal clock up to date if an RTP frame should be
 * send at a given time but no audio content is available. When next packet is
 * sent, the receiver will see a different increase on the sequence number and
 * the timestamp, and it should then take it as a synchronization point. For
 * that same reason, it is advisable to enable the marker bit on the next RTP
 * packet to be sent after calling this function.
 *
 *  \returns 0 on success, <0 in case of error.
 */
int osmo_rtp_skipped_frame(struct osmo_rtp_socket *rs, unsigned int duration)
{
	if (rs->flags & OSMO_RTP_F_DISABLED)
		return 0;

	rs->tx_timestamp += duration;
	return 0;
}

/*! \brief Send one RTP frame via a RTP socket
 *  \param[in] rs OsmoRTP socket
 *  \param[in] payload pointer to buffer with RTP payload data
 *  \param[in] payload_len length of \a payload in bytes
 *  \param[in] duration duration in number of RTP clock ticks
 *  \returns 0 on success, <0 in case of error.
 */
int osmo_rtp_send_frame(struct osmo_rtp_socket *rs, const uint8_t *payload,
			unsigned int payload_len, unsigned int duration)
{
	return osmo_rtp_send_frame_ext(rs, payload, payload_len, duration,
				       false);
}

/*! \brief Send one RTP frame via a RTP socket
 *  \param[in] rs OsmoRTP socket
 *  \param[in] payload pointer to buffer with RTP payload data
 *  \param[in] payload_len length of \a payload in bytes
 *  \param[in] duration duration in number of RTP clock ticks
 *  \param[in] marker the status of Marker bit in RTP header
 *  \returns 0 on success, <0 in case of error.
 */
int osmo_rtp_send_frame_ext(struct osmo_rtp_socket *rs, const uint8_t *payload,
			unsigned int payload_len, unsigned int duration,
			bool marker)
{
	mblk_t *mblk;
	int rc;

	if (rs->flags & OSMO_RTP_F_DISABLED)
		return 0;

	mblk = rtp_session_create_packet(rs->sess, RTP_FIXED_HEADER_SIZE,
					 payload, payload_len);
	if (!mblk)
		return -ENOMEM;

	rtp_set_markbit(mblk, marker);
	rc = rtp_session_sendm_with_ts(rs->sess, mblk,
				       rs->tx_timestamp);
	rs->tx_timestamp += duration;
	if (rc < 0) {
		/* no need to free() the mblk, as rtp_session_rtp_send()
		 * unconditionally free()s the mblk even in case of
		 * error */
		return rc;
	}

	return rc;
}

/*! \brief Set the payload type of a RTP socket
 *  \param[in] rs OsmoRTP socket
 *  \param[in] payload_type RTP payload type
 *  \returns 0 on success, < 0 otherwise
 */
int osmo_rtp_socket_set_pt(struct osmo_rtp_socket *rs, int payload_type)
{
	int rc;

	rc = rtp_session_set_payload_type(rs->sess, payload_type);
	//rtp_session_set_rtcp_report_interval(rs->sess, 5*1000);

	return rc;
}

/*! \brief Set the DSCP (Differentiated Services Code Point) for outgoing RTP packets
 *  \param[in] rs OsmoRTP socket
 *  \param[in] dscp DSCP value
 *  \returns 0 on success, < 0 otherwise
 */
int osmo_rtp_socket_set_dscp(struct osmo_rtp_socket *rs, int dscp)
{
	return rtp_session_set_dscp(rs->sess, dscp);
}

/*! \brief Set the socket priority for outgoing RTP packets
 *  \param[in] rs OsmoRTP socket
 *  \param[in] prio socket priority
 *  \returns 0 on success, < 0 otherwise
 */
int osmo_rtp_socket_set_priority(struct osmo_rtp_socket *rs, uint8_t prio)
{
	int rc;

	rc = osmo_sock_set_priority(rs->rtp_bfd.fd, prio);
	if (rc < 0)
		return rc;
	return osmo_sock_set_priority(rs->rtcp_bfd.fd, prio);
}

/*! \brief completely close the RTP socket and release all resources
 *  \param[in] rs OsmoRTP socket to be released
 *  \returns 0 on success
 */
int osmo_rtp_socket_free(struct osmo_rtp_socket *rs)
{
	if (rs->rtp_bfd.list.next && rs->rtp_bfd.list.next != LLIST_POISON1)
		osmo_fd_unregister(&rs->rtp_bfd);

	if (rs->rtcp_bfd.list.next && rs->rtcp_bfd.list.next != LLIST_POISON1)
		osmo_fd_unregister(&rs->rtcp_bfd);

	if (rs->sess) {
		rtp_session_release_sockets(rs->sess);
		rtp_session_destroy(rs->sess);
		rs->sess = NULL;
	}

	talloc_free(rs);

	return 0;
}

/*! \brief obtain the locally bound IPv4 address and UDP port
 *  \param[in] rs OsmoRTP socket
 *  \param[out] ip Pointer to caller-allocated uint32_t for IPv4 address
 *  \oaram[out] port Pointer to caller-allocated int for UDP port number
 *  \returns 0 on success, <0 on error, -EIO in case of IPv6 socket
 */
int osmo_rtp_get_bound_ip_port(struct osmo_rtp_socket *rs,
			       uint32_t *ip, int *port)
{
	int rc;
	struct sockaddr_storage ss;
	struct sockaddr_in *sin = (struct sockaddr_in *) &ss;
	socklen_t alen = sizeof(ss);

	rc = getsockname(rs->rtp_bfd.fd, (struct sockaddr *)&ss, &alen);
	if (rc < 0)
		return rc;

	if (ss.ss_family != AF_INET)
		return -EIO;

	*ip = ntohl(sin->sin_addr.s_addr);
	*port = rtp_session_get_local_port(rs->sess);

	return 0;
}

/*! \brief obtain the locally bound address and port
 *  \param[in] rs OsmoRTP socket
 *  \param[out] addr caller-allocated char ** to which the string pointer for
 *  		     the address is stored
 *  \param[out] port caller-allocated int * to which the port number is
 *  		     stored
 *  \returns 0 on success, <0 in case of error
 */
int osmo_rtp_get_bound_addr(struct osmo_rtp_socket *rs,
			    const char **addr, int *port)
{
	int rc;
	struct sockaddr_storage ss;
	socklen_t alen = sizeof(ss);
	static char hostbuf[256];

	memset(hostbuf, 0, sizeof(hostbuf));

	rc = getsockname(rs->rtp_bfd.fd, (struct sockaddr *)&ss, &alen);
	if (rc < 0)
		return rc;

	rc = getnameinfo((struct sockaddr *)&ss, alen,
			 hostbuf, sizeof(hostbuf), NULL, 0,
			 NI_NUMERICHOST);
	if (rc < 0)
		return rc;

	*port = rtp_session_get_local_port(rs->sess);
	*addr = hostbuf;

	return 0;
}


void osmo_rtp_socket_log_stats(struct osmo_rtp_socket *rs,
				int subsys, int level,
				const char *pfx)
{
	const rtp_stats_t *stats;

	stats = rtp_session_get_stats(rs->sess);
	if (!stats)
		return;

	LOGP(subsys, level, "%sRTP Tx(%"PRIu64" pkts, %"PRIu64" bytes) "
		"Rx(%"PRIu64" pkts, %"PRIu64" bytes, %"PRIu64" late, "
		"%"PRIu64" loss, %"PRIu64" qmax)\n",
		pfx, stats->packet_sent, stats->sent,
		stats->packet_recv, stats->hw_recv, stats->outoftime,
		stats->cum_packet_loss, stats->discarded);
}

void osmo_rtp_socket_stats(struct osmo_rtp_socket *rs,
		uint32_t *sent_packets, uint32_t *sent_octets,
		uint32_t *recv_packets, uint32_t *recv_octets,
		uint32_t *recv_lost, uint32_t *last_jitter)
{
	const rtp_stats_t *stats;

	*sent_packets = *sent_octets = *recv_packets = *recv_octets = 0;
	*recv_lost = *last_jitter = 0;

	stats = rtp_session_get_stats(rs->sess);
	if (stats) {
		/* truncate from 64bit to 32bit here */
		*sent_packets = stats->packet_sent;
		*sent_octets = stats->sent;
		*recv_packets = stats->packet_recv;
		*recv_octets = stats->recv;
		*recv_lost = stats->cum_packet_loss;
	}

	const jitter_stats_t *jitter;

	jitter = rtp_session_get_jitter_stats(rs->sess);
	if (jitter)
		*last_jitter = jitter->jitter;
}

void osmo_rtp_set_source_desc(struct osmo_rtp_socket *rs, const char *cname,
				const char *name, const char *email, const char *phone,
				const char *loc, const char *tool, const char *note)
{
	rtp_session_set_source_description(rs->sess, cname, name, email, phone, loc, tool, note);
}
