/*
 * (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
 * (C) 2016 by Tom Tsou <tom.tsou@ettus.com>
 *
 * All Rights Reserved
 *
 * 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.
 */

#include <stdint.h>
#include <string.h>

#include <osmocom/core/bits.h>
#include <osmocom/coding/gsm0503_mapping.h>

/*! \addtogroup mapping
 *  @{
 *
 *  GSM TS 05.03 burst mapping
 *
 *  This module contains burst mapping routines as specified in 3GPP TS
 *  05.03 / 45.003.
 */

/*! \file gsm0503_mapping.c */

void gsm0503_xcch_burst_unmap(sbit_t *iB, const sbit_t *eB,
	sbit_t *hl, sbit_t *hn)
{
	memcpy(iB,      eB,      57);
	memcpy(iB + 57, eB + 59, 57);

	if (hl)
		*hl = eB[57];

	if (hn)
		*hn = eB[58];
}

void gsm0503_xcch_burst_map(const ubit_t *iB, ubit_t *eB, const ubit_t *hl,
	const ubit_t *hn)
{
	memcpy(eB,      iB,      57);
	memcpy(eB + 59, iB + 57, 57);

	if (hl)
		eB[57] = *hl;
	if (hn)
		eB[58] = *hn;
}

void gsm0503_tch_burst_unmap(sbit_t *iB, const sbit_t *eB, sbit_t *h, int odd)
{
	int i;

	/* brainfuck: only copy even or odd bits */
	if (iB) {
		for (i = odd; i < 57; i += 2)
			iB[i] = eB[i];
		for (i = 58 - odd; i < 114; i += 2)
			iB[i] = eB[i + 2];
	}

	if (h) {
		if (!odd)
			*h = eB[58];
		else
			*h = eB[57];
	}
}

void gsm0503_tch_burst_map(const ubit_t *iB, ubit_t *eB, const ubit_t *h, int odd)
{
	int i;

	/* brainfuck: only copy even or odd bits */
	if (eB) {
		for (i = odd; i < 57; i += 2)
			eB[i] = iB[i];
		for (i = 58 - odd; i < 114; i += 2)
			eB[i + 2] = iB[i];
	}

	if (h) {
		if (!odd)
			eB[58] = *h;
		else
			eB[57] = *h;
	}
}

void gsm0503_mcs5_dl_burst_map(const ubit_t *di, ubit_t *eB,
	const ubit_t *hi, const ubit_t *up, int B)
{
	int j;
	int q[8] = { 0, 0, 0, 0, 0, 0, 0, 0, };

	for (j = 0; j < 156; j++)
		eB[j] = di[312 * B + j];
	for (j = 156; j < 168; j++)
		eB[j] = hi[25 * B + j - 156];
	for (j = 168; j < 174; j++)
		eB[j] = up[9 * B + j - 168];
	for (j = 174; j < 176; j++)
		eB[j] = q[2 * B + j - 174];
	for (j = 176; j < 179; j++)
		eB[j] = up[9 * B + j - 170];
	for (j = 179; j < 192; j++)
		eB[j] = hi[25 * B + j - 167];
	for (j = 192; j < 348; j++)
		eB[j] = di[312 * B + j - 36];
}

void gsm0503_mcs5_dl_burst_unmap(sbit_t *di, const sbit_t *eB,
	sbit_t *hi, sbit_t *up, int B)
{
	int j;

	for (j = 0; j < 156; j++)
		di[312 * B + j] = eB[j];
	for (j = 156; j < 168; j++)
		hi[25 * B + j - 156] = eB[j];
	for (j = 168; j < 174; j++)
		up[9 * B + j - 168] = eB[j];

	for (j = 176; j < 179; j++)
		up[9 * B + j - 170] = eB[j];
	for (j = 179; j < 192; j++)
		hi[25 * B + j - 167] = eB[j];
	for (j = 192; j < 348; j++)
		di[312 * B + j - 36] = eB[j];
}

void gsm0503_mcs5_ul_burst_map(const ubit_t *di, ubit_t *eB,
	const ubit_t *hi, int B)
{
	int j;

	for (j = 0; j < 156; j++)
		eB[j] = di[312 * B + j];
	for (j = 156; j < 174; j++)
		eB[j] = hi[34 * B + j - 156];
	for (j = 174; j < 176; j++)
		eB[j] = 0;
	for (j = 176; j < 192; j++)
		eB[j] = hi[34 * B + j - 158];
	for (j = 192; j < 348; j++)
		eB[j] = di[312 * B + j - 36];
}

void gsm0503_mcs5_ul_burst_unmap(sbit_t *di, const sbit_t *eB,
	sbit_t *hi, int B)
{
	int j;

	for (j = 0; j < 156; j++)
		di[312 * B + j] = eB[j];
	for (j = 156; j < 174; j++)
		hi[34 * B + j - 156] = eB[j];
	for (j = 176; j < 192; j++)
		hi[34 * B + j - 158] = eB[j];
	for (j = 192; j < 348; j++)
		di[312 * B + j - 36] = eB[j];
}

void gsm0503_mcs7_dl_burst_map(const ubit_t *di, ubit_t *eB,
	const ubit_t *hi, const ubit_t *up, int B)
{
	int j;
	int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, };

	for (j = 0; j < 153; j++)
		eB[j] = di[306 * B + j];
	for (j = 153; j < 168; j++)
		eB[j] = hi[31 * B + j - 153];
	for (j = 168; j < 174; j++)
		eB[j] = up[9 * B + j - 168];
	for (j = 174; j < 176; j++)
		eB[j] = q[2 * B + j - 174];
	for (j = 176; j < 179; j++)
		eB[j] = up[9 * B + j - 170];
	for (j = 179; j < 195; j++)
		eB[j] = hi[31 * B + j - 164];
	for (j = 195; j < 348; j++)
		eB[j] = di[306 * B + j - 42];
}

void gsm0503_mcs7_dl_burst_unmap(sbit_t *di, const sbit_t *eB,
	sbit_t *hi, sbit_t *up, int B)
{
	int j;

	for (j = 0; j < 153; j++)
		di[306 * B + j] = eB[j];
	for (j = 153; j < 168; j++)
		hi[31 * B + j - 153] = eB[j];
	for (j = 168; j < 174; j++)
		up[9 * B + j - 168] = eB[j];

	for (j = 176; j < 179; j++)
		up[9 * B + j - 170] = eB[j];
	for (j = 179; j < 195; j++)
		hi[31 * B + j - 164] = eB[j];
	for (j = 195; j < 348; j++)
		di[306 * B + j - 42] = eB[j];
}

void gsm0503_mcs7_ul_burst_map(const ubit_t *di, ubit_t *eB,
	const ubit_t *hi, int B)
{
	int j;
	int q[8] = { 1, 1, 1, 0, 0, 1, 1, 1, };

	for (j = 0; j < 153; j++)
		eB[j] = di[306 * B + j];
	for (j = 153; j < 174; j++)
		eB[j] = hi[40 * B + j - 153];
	for (j = 174; j < 176; j++)
		eB[j] = q[2 * B + j - 174];
	for (j = 176; j < 195; j++)
		eB[j] = hi[40 * B + j - 155];
	for (j = 195; j < 348; j++)
		eB[j] = di[306 * B + j - 42];
}

void gsm0503_mcs7_ul_burst_unmap(sbit_t *di, const sbit_t *eB,
	sbit_t *hi, int B)
{
	int j;

	for (j = 0; j < 153; j++)
		di[306 * B + j] = eB[j];
	for (j = 153; j < 174; j++)
		hi[40 * B + j - 153] = eB[j];

	for (j = 176; j < 195; j++)
		hi[40 * B + j - 155] = eB[j];
	for (j = 195; j < 348; j++)
		di[306 * B + j - 42] = eB[j];
}

void gsm0503_mcs5_burst_swap(sbit_t *eB)
{
	sbit_t t[14];

	t[0]  = eB[155];
	t[1]  = eB[158];
	t[2]  = eB[161];
	t[3]  = eB[164];
	t[4]  = eB[167];
	t[5]  = eB[170];
	t[6]  = eB[173];
	t[7]  = eB[195];
	t[8]  = eB[196];
	t[9]  = eB[198];
	t[10] = eB[199];
	t[11] = eB[201];
	t[12] = eB[202];
	t[13] = eB[204];

	eB[155] = eB[142];
	eB[158] = eB[144];
	eB[161] = eB[145];
	eB[164] = eB[147];
	eB[167] = eB[148];
	eB[170] = eB[150];
	eB[173] = eB[151];
	eB[195] = eB[176];
	eB[196] = eB[179];
	eB[198] = eB[182];
	eB[199] = eB[185];
	eB[201] = eB[188];
	eB[202] = eB[191];
	eB[204] = eB[194];

	eB[142] = t[0];
	eB[144] = t[1];
	eB[145] = t[2];
	eB[147] = t[3];
	eB[148] = t[4];
	eB[150] = t[5];
	eB[151] = t[6];
	eB[176] = t[7];
	eB[179] = t[8];
	eB[182] = t[9];
	eB[185] = t[10];
	eB[188] = t[11];
	eB[191] = t[12];
	eB[194] = t[13];
}

/*! @} */
