/* Measurements
 *
 * Copyright (C) 2012 Andreas Eversberg <jolly@eversberg.eu>
 *
 * 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.
 */

extern "C" {
#include <osmocom/core/timer_compat.h>
}

#include <gprs_rlcmac.h>
#include <gprs_debug.h>
#include <pcu_l1_if.h>
#include <tbf.h>
#include <tbf_dl.h>
#include <gprs_ms.h>

#include <string.h>
#include <errno.h>

/*
 * downlink measurement
 */
/* TODO: trigger the measurement report from the pollcontroller and use it for flow control */

/* received Measurement Report */
int gprs_rlcmac_meas_rep(GprsMs *ms, Packet_Measurement_Report_t *pmr)
{
	NC_Measurement_Report_t *ncr;
	NC_Measurements_t *nc;
	int i;

	LOGPMS(ms, DRLCMACMEAS, LOGL_INFO, "Rx Measurement Report:");

	switch (pmr->UnionType) {
	case 0:
		ncr = &pmr->u.NC_Measurement_Report;
		LOGPC(DRLCMACMEAS, LOGL_INFO, " NC%u Serv %d dbm",
			ncr->NC_MODE + 1,
			ncr->Serving_Cell_Data.RXLEV_SERVING_CELL - 110);
		for (i = 0; i < ncr->NUMBER_OF_NC_MEASUREMENTS; i++) {
			nc = &ncr->NC_Measurements[i];
			LOGPC(DRLCMACMEAS, LOGL_DEBUG, ", Neigh %u %d dbm",
				nc->FREQUENCY_N, nc->RXLEV_N - 110);
		}
		LOGPC(DRLCMACMEAS, LOGL_INFO, "\n");

		break;
	case 1:
		LOGPC(DRLCMACMEAS, LOGL_INFO,
			" <EXT Reporting not supported!>\n");
		break;
	}

	return 0;
}


/*
 * uplink measurement
 */

/* RSSI values received from MS */
int gprs_rlcmac_rssi(struct gprs_rlcmac_tbf *tbf, int8_t rssi)
{
	struct timespec now_tv, *rssi_tv = &tbf->meas.rssi_tv;
	struct timespec elapsed;

	tbf->meas.rssi_sum += rssi;
	tbf->meas.rssi_num++;

	osmo_clock_gettime(CLOCK_MONOTONIC, &now_tv);

	timespecsub(&now_tv, rssi_tv, &elapsed);
	if (elapsed.tv_sec < 1)
		return 0;

	gprs_rlcmac_rssi_rep(tbf);

	/* reset rssi values and timestamp */
	memcpy(rssi_tv, &now_tv, sizeof(*rssi_tv));
	tbf->meas.rssi_sum = 0;
	tbf->meas.rssi_num = 0;

	return 0;
}

/* Give RSSI report */
int gprs_rlcmac_rssi_rep(struct gprs_rlcmac_tbf *tbf)
{
	/* No measurement values */
	if (!tbf->meas.rssi_num)
		return -EINVAL;

	LOGPMS(tbf->ms(), DRLCMACMEAS, LOGL_INFO, "UL RSSI: %d dBm\n",
	       tbf->meas.rssi_sum / tbf->meas.rssi_num);

	return 0;
}


/*
 * lost frames
 */

/* Lost frames reported from RLCMAC layer */
int gprs_rlcmac_received_lost(struct gprs_rlcmac_dl_tbf *tbf, uint16_t received,
	uint16_t lost)
{
	struct timespec now_tv, *loss_tv = &tbf->m_bw.dl_loss_tv;
	struct timespec elapsed;
	uint16_t sum = received + lost;

	/* No measurement values */
	if (!sum)
		return -EINVAL;

	LOGP(DRLCMACMEAS, LOGL_DEBUG, "%s DL Loss: Received: %4d Lost: %4d  Sum: %4d\n",
	     tbf_name(dl_tbf_as_tbf_const(tbf)), received, lost, sum);

	tbf->m_bw.dl_loss_received += received;
	tbf->m_bw.dl_loss_lost += lost;

	osmo_clock_gettime(CLOCK_MONOTONIC, &now_tv);
	timespecsub(&now_tv, loss_tv, &elapsed);
	if (elapsed.tv_sec < 1)
		return 0;

	gprs_rlcmac_lost_rep(tbf);

	/* reset lost values and timestamp */
	memcpy(loss_tv, &now_tv, sizeof(*loss_tv));
	tbf->m_bw.dl_loss_received = 0;
	tbf->m_bw.dl_loss_lost = 0;

	return 0;
}

/* Give Lost report */
int gprs_rlcmac_lost_rep(struct gprs_rlcmac_dl_tbf *tbf)
{
	uint16_t sum = tbf->m_bw.dl_loss_lost + tbf->m_bw.dl_loss_received;

	/* No measurement values */
	if (!sum)
		return -EINVAL;

	LOGP(DRLCMACMEAS, LOGL_DEBUG, "%s DL packet loss: %d%%\n",
	     tbf_name(dl_tbf_as_tbf_const(tbf)), tbf->m_bw.dl_loss_lost * 100 / sum);

	return 0;
}


/*
 * downlink bandwidth
 */

int gprs_rlcmac_dl_bw(struct gprs_rlcmac_dl_tbf *tbf, uint16_t octets)
{
	struct timespec now_tv, *bw_tv = &tbf->m_bw.dl_bw_tv;
	struct timespec elapsed;

	tbf->m_bw.dl_bw_octets += octets;

	osmo_clock_gettime(CLOCK_MONOTONIC, &now_tv);
	timespecsub(&now_tv, bw_tv, &elapsed);
	if (elapsed.tv_sec < 1)
		return 0;

	tbf->m_bw.dl_throughput = (tbf->m_bw.dl_bw_octets << 10) / ((elapsed.tv_sec << 10) + (elapsed.tv_nsec >> 20));
	LOGP(DRLCMACMEAS, LOGL_INFO, "%s DL Bandwitdh: %d KBits/s\n",
	     tbf_name(dl_tbf_as_tbf_const(tbf)), tbf->m_bw.dl_throughput);

	/* reset bandwidth values timestamp */
	memcpy(bw_tv, &now_tv, sizeof(*bw_tv));
	tbf->m_bw.dl_bw_octets = 0;

	return 0;
}
