/*
 * Copyright (C) 2019 sysmocom - s.f.m.c. GmbH
 * All Rights Reserved
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * Author: Pau Espin Pedrol <pespin@sysmocom.de>
 *
 * 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/>.
 * See the COPYING file in the main directory for details.
 */

#include "proto_trxd.h"

#include <osmocom/core/bits.h>

static void trxd_fill_common(struct trxd_hdr_common *common, const struct trx_ul_burst_ind *bi, uint8_t version)
{
	common->version = version & 0b1111;
	common->reserved = 0;
	common->tn = bi->tn;
	osmo_store32be(bi->fn, &common->fn);
}

static void trxd_fill_v0_specific(struct trxd_hdr_v0_specific *v0, const struct trx_ul_burst_ind *bi)
{
	int toa_int;

	/* in 1/256 symbols, round to closest integer */
	toa_int = (int) (bi->toa * 256.0 + 0.5);
	v0->rssi = bi->rssi;
	osmo_store16be(toa_int, &v0->toa);
}

static void trxd_fill_v1_specific(struct trxd_hdr_v1_specific *v1, const struct trx_ul_burst_ind *bi)
{
	int16_t ci_int_cB;

	/* deciBels->centiBels, round to closest integer */
	ci_int_cB = (int16_t)((bi->ci * 10) + 0.5);

	v1->idle = !!bi->idle;
	v1->modulation = (bi->modulation == MODULATION_GMSK) ?
					TRXD_MODULATION_GMSK(bi->tss) :
					TRXD_MODULATION_8PSK(bi->tss);
	v1->tsc = bi->tsc;
	osmo_store16be(ci_int_cB, &v1->ci);
}

static void trxd_fill_burst_normalized255(uint8_t* soft_bits, const struct trx_ul_burst_ind *bi)
{
	unsigned i;
	for (i = 0; i < bi->nbits; i++)
		soft_bits[i] = (uint8_t) round(bi->rx_burst[i] * 255.0);
}

bool trxd_send_burst_ind_v0(size_t chan, int fd, const struct trx_ul_burst_ind *bi) {
	int rc;

	/* v0 doesn't support idle frames, they are simply dropped, not sent */
	if (bi->idle)
		return true;

	/* +2: Historically (OpenBTS times), two extra non-used bytes are sent appended to each burst */
	char buf[sizeof(struct trxd_hdr_v0) + bi->nbits + 2];
	struct trxd_hdr_v0* pkt = (struct trxd_hdr_v0*)buf;

	trxd_fill_common(&pkt->common, bi, 0);
	trxd_fill_v0_specific(&pkt->v0, bi);
	trxd_fill_burst_normalized255(&pkt->soft_bits[0], bi);

	/* +1: Historical reason. There's an uninitizalied byte in there: pkt->soft_bits[bi->nbits] */
	pkt->soft_bits[bi->nbits + 1] = '\0';

	rc = write(fd, buf, sizeof(struct trxd_hdr_v0) + bi->nbits + 2);
	if (rc <= 0) {
		CLOGCHAN(chan, DMAIN, LOGL_NOTICE, "mDataSockets write(%d) failed: %d\n", fd, rc);
		return false;
	}
	return true;
}

bool trxd_send_burst_ind_v1(size_t chan, int fd, const struct trx_ul_burst_ind *bi) {
	int rc;
	size_t buf_len;

	buf_len = sizeof(struct trxd_hdr_v1);
	if (!bi->idle)
		buf_len += bi->nbits;
	char buf[buf_len];

	struct trxd_hdr_v1* pkt = (struct trxd_hdr_v1*)buf;
	trxd_fill_common(&pkt->common, bi, 1);
	trxd_fill_v0_specific(&pkt->v0, bi);
	trxd_fill_v1_specific(&pkt->v1, bi);

	if (!bi->idle)
		trxd_fill_burst_normalized255(&pkt->soft_bits[0], bi);

	rc = write(fd, buf, buf_len);
	if (rc <= 0) {
		CLOGCHAN(chan, DMAIN, LOGL_NOTICE, "mDataSockets write(%d) failed: %d\n", fd, rc);
		return false;
	}
	return true;
}
