/* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
/* The statistics generator */

/*
 * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2009-2012 by On-Waves
 * (C) 2017 by sysmocom s.f.m.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 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 Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <limits.h>
#include <inttypes.h>
#include <osmocom/mgcp/mgcp_protocol.h>
#include <osmocom/mgcp/mgcp_conn.h>
#include <osmocom/mgcp/mgcp_stat.h>
#include <osmocom/mgcp/mgcp_endp.h>
#include <osmocom/mgcp/mgcp_trunk.h>

/* Helper function for mgcp_format_stats_rtp() to calculate packet loss */
#if defined(__has_attribute)
#if __has_attribute(no_sanitize)
__attribute__((no_sanitize("undefined")))
#endif
#endif
void calc_loss(struct mgcp_conn_rtp *conn, uint32_t *expected, int *loss)
{
	struct mgcp_rtp_state *state = &conn->state;
	struct rate_ctr *packets_rx = rate_ctr_group_get_ctr(conn->rate_ctr_group, RTP_PACKETS_RX_CTR);

	*expected = state->stats.cycles + state->stats.max_seq;
	*expected = *expected - state->stats.base_seq + 1;

	if (!state->stats.initialized) {
		*expected = 0;
		*loss = 0;
		return;
	}

	/*
	 * Make sure the sign is correct and use the biggest
	 * positive/negative number that fits.
	 */
	*loss = *expected - packets_rx->current;
	if (*expected < packets_rx->current) {
		if (*loss > 0)
			*loss = INT_MIN;
	} else {
		if (*loss < 0)
			*loss = INT_MAX;
	}
}

/* Helper function for mgcp_format_stats_rtp() to calculate jitter */
uint32_t calc_jitter(struct mgcp_rtp_state *state)
{
	if (!state->stats.initialized)
		return 0;
	return state->stats.jitter >> 4;
}

/* Generate statistics for an RTP connection */
static void mgcp_format_stats_rtp(char *str, size_t str_len,
				  struct mgcp_conn_rtp *conn)
{
	uint32_t expected, jitter;
	int ploss;
	int nchars;

	struct rate_ctr *packets_rx = rate_ctr_group_get_ctr(conn->rate_ctr_group, RTP_PACKETS_RX_CTR);
	struct rate_ctr *octets_rx = rate_ctr_group_get_ctr(conn->rate_ctr_group, RTP_OCTETS_RX_CTR);
	struct rate_ctr *packets_tx = rate_ctr_group_get_ctr(conn->rate_ctr_group, RTP_PACKETS_TX_CTR);
	struct rate_ctr *octets_tx = rate_ctr_group_get_ctr(conn->rate_ctr_group, RTP_OCTETS_TX_CTR);

	calc_loss(conn, &expected, &ploss);
	jitter = calc_jitter(&conn->state);

	nchars = snprintf(str, str_len,
			  "\r\nP: PS=%" PRIu64 ", OS=%" PRIu64 ", PR=%" PRIu64 ", OR=%" PRIu64 ", PL=%d, JI=%u",
			  packets_tx->current, octets_tx->current,
			  packets_rx->current, octets_rx->current,
			  ploss, jitter);
	if (nchars < 0 || nchars >= str_len)
		goto truncate;

	str += nchars;
	str_len -= nchars;

	if (conn->conn->endp->trunk->cfg->osmux != OSMUX_USAGE_OFF) {
		/* Error Counter */
		nchars = snprintf(str, str_len,
				  "\r\nX-Osmo-CP: EC TI=%" PRIu64 ", TO=%" PRIu64,
				  conn->state.in_stream.err_ts_ctr->current,
				  conn->state.out_stream.err_ts_ctr->current);
		if (nchars < 0 || nchars >= str_len)
			goto truncate;

		str += nchars;
		str_len -= nchars;

		if (conn->osmux.state == OSMUX_STATE_ENABLED) {
			snprintf(str, str_len,
				 "\r\nX-Osmux-ST: CR=%u, BR=%u",
				 conn->osmux.stats.chunks, conn->osmux.stats.octets);
		}
	}

truncate:
	str[str_len - 1] = '\0';
}

/*! format statistics into an mgcp parameter string.
 *  \param[out] str resulting string
 *  \param[in] str_len length of the string buffer
 *  \param[in] conn connection to evaluate */
void mgcp_format_stats(char *str, size_t str_len, struct mgcp_conn *conn)
{
	memset(str, 0, str_len);
	if (!conn)
		return;

	/* NOTE: At the moment we only support generating statistics for
	 * RTP connections. However, in the future we may also want to
	 * generate statistics for other connection types as well. Lets
	 * keep this option open: */
	switch (conn->type) {
	case MGCP_CONN_TYPE_RTP:
		mgcp_format_stats_rtp(str, str_len, &conn->u.rtp);
		break;
	default:
		break;
	}
}
