/*! \file gsm610.c
 * GSM 06.10 - GSM FR codec. */
/*
 * (C) 2010 Sylvain Munaut <tnt@246tNt.com>
 *
 * 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.
 *
 */

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

#include <osmocom/core/bitvec.h>
#include <osmocom/core/utils.h>
#include <osmocom/codec/codec.h>

/* GSM FR - subjective importance bit ordering */
	/* This array encodes GSM 05.03 Table 2.
	 * It's also GSM 06.10 Table A.2.1a
	 *
	 * It converts between serial parameter output by the encoder and the
	 * order needed before channel encoding.
	 */
const uint16_t gsm610_bitorder[260] = {
	0,	/* LARc0:5 */
	47,	/* Xmaxc0:5 */
	103,	/* Xmaxc1:5 */
	159,	/* Xmaxc2:5 */
	215,	/* Xmaxc3:5 */
	1,	/* LARc0:4 */
	6,	/* LARc1:5 */
	12,	/* LARc2:4 */
	2,	/* LARc0:3 */
	7,	/* LARc1:4 */
	13,	/* LARc2:3 */
	17,	/* LARc3:4 */
	36,	/* Nc0:6 */
	92,	/* Nc1:6 */
	148,	/* Nc2:6 */
	204,	/* Nc3:6 */
	48,	/* Xmaxc0:4 */
	104,	/* Xmaxc1:4 */
	160,	/* Xmaxc2:4 */
	216,	/* Xmaxc3:4 */
	8,	/* LARc1:3 */
	22,	/* LARc4:3 */
	26,	/* LARc5:3 */
	37,	/* Nc0:5 */
	93,	/* Nc1:5 */
	149,	/* Nc2:5 */
	205,	/* Nc3:5 */
	38,	/* Nc0:4 */
	94,	/* Nc1:4 */
	150,	/* Nc2:4 */
	206,	/* Nc3:4 */
	39,	/* Nc0:3 */
	95,	/* Nc1:3 */
	151,	/* Nc2:3 */
	207,	/* Nc3:3 */
	40,	/* Nc0:2 */
	96,	/* Nc1:2 */
	152,	/* Nc2:2 */
	208,	/* Nc3:2 */
	49,	/* Xmaxc0:3 */
	105,	/* Xmaxc1:3 */
	161,	/* Xmaxc2:3 */
	217,	/* Xmaxc3:3 */
	3,	/* LARc0:2 */
	18,	/* LARc3:3 */
	30,	/* LARc6:2 */
	41,	/* Nc0:1 */
	97,	/* Nc1:1 */
	153,	/* Nc2:1 */
	209,	/* Nc3:1 */
	23,	/* LARc4:2 */
	27,	/* LARc5:2 */
	43,	/* bc0:1 */
	99,	/* bc1:1 */
	155,	/* bc2:1 */
	211,	/* bc3:1 */
	42,	/* Nc0:0 */
	98,	/* Nc1:0 */
	154,	/* Nc2:0 */
	210,	/* Nc3:0 */
	45,	/* Mc0:1 */
	101,	/* Mc1:1 */
	157,	/* Mc2:1 */
	213,	/* Mc3:1 */
	4,	/* LARc0:1 */
	9,	/* LARc1:2 */
	14,	/* LARc2:2 */
	33,	/* LARc7:2 */
	19,	/* LARc3:2 */
	24,	/* LARc4:1 */
	31,	/* LARc6:1 */
	44,	/* bc0:0 */
	100,	/* bc1:0 */
	156,	/* bc2:0 */
	212,	/* bc3:0 */
	50,	/* Xmaxc0:2 */
	106,	/* Xmaxc1:2 */
	162,	/* Xmaxc2:2 */
	218,	/* Xmaxc3:2 */
	53,	/* xmc0_0:2 */
	56,	/* xmc0_1:2 */
	59,	/* xmc0_2:2 */
	62,	/* xmc0_3:2 */
	65,	/* xmc0_4:2 */
	68,	/* xmc0_5:2 */
	71,	/* xmc0_6:2 */
	74,	/* xmc0_7:2 */
	77,	/* xmc0_8:2 */
	80,	/* xmc0_9:2 */
	83,	/* xmc0_10:2 */
	86,	/* xmc0_11:2 */
	89,	/* xmc0_12:2 */
	109,	/* xmc1_0:2 */
	112,	/* xmc1_1:2 */
	115,	/* xmc1_2:2 */
	118,	/* xmc1_3:2 */
	121,	/* xmc1_4:2 */
	124,	/* xmc1_5:2 */
	127,	/* xmc1_6:2 */
	130,	/* xmc1_7:2 */
	133,	/* xmc1_8:2 */
	136,	/* xmc1_9:2 */
	139,	/* xmc1_10:2 */
	142,	/* xmc1_11:2 */
	145,	/* xmc1_12:2 */
	165,	/* xmc2_0:2 */
	168,	/* xmc2_1:2 */
	171,	/* xmc2_2:2 */
	174,	/* xmc2_3:2 */
	177,	/* xmc2_4:2 */
	180,	/* xmc2_5:2 */
	183,	/* xmc2_6:2 */
	186,	/* xmc2_7:2 */
	189,	/* xmc2_8:2 */
	192,	/* xmc2_9:2 */
	195,	/* xmc2_10:2 */
	198,	/* xmc2_11:2 */
	201,	/* xmc2_12:2 */
	221,	/* xmc3_0:2 */
	224,	/* xmc3_1:2 */
	227,	/* xmc3_2:2 */
	230,	/* xmc3_3:2 */
	233,	/* xmc3_4:2 */
	236,	/* xmc3_5:2 */
	239,	/* xmc3_6:2 */
	242,	/* xmc3_7:2 */
	245,	/* xmc3_8:2 */
	248,	/* xmc3_9:2 */
	251,	/* xmc3_10:2 */
	254,	/* xmc3_11:2 */
	257,	/* xmc3_12:2 */
	46,	/* Mc0:0 */
	102,	/* Mc1:0 */
	158,	/* Mc2:0 */
	214,	/* Mc3:0 */
	51,	/* Xmaxc0:1 */
	107,	/* Xmaxc1:1 */
	163,	/* Xmaxc2:1 */
	219,	/* Xmaxc3:1 */
	54,	/* xmc0_0:1 */
	57,	/* xmc0_1:1 */
	60,	/* xmc0_2:1 */
	63,	/* xmc0_3:1 */
	66,	/* xmc0_4:1 */
	69,	/* xmc0_5:1 */
	72,	/* xmc0_6:1 */
	75,	/* xmc0_7:1 */
	78,	/* xmc0_8:1 */
	81,	/* xmc0_9:1 */
	84,	/* xmc0_10:1 */
	87,	/* xmc0_11:1 */
	90,	/* xmc0_12:1 */
	110,	/* xmc1_0:1 */
	113,	/* xmc1_1:1 */
	116,	/* xmc1_2:1 */
	119,	/* xmc1_3:1 */
	122,	/* xmc1_4:1 */
	125,	/* xmc1_5:1 */
	128,	/* xmc1_6:1 */
	131,	/* xmc1_7:1 */
	134,	/* xmc1_8:1 */
	137,	/* xmc1_9:1 */
	140,	/* xmc1_10:1 */
	143,	/* xmc1_11:1 */
	146,	/* xmc1_12:1 */
	166,	/* xmc2_0:1 */
	169,	/* xmc2_1:1 */
	172,	/* xmc2_2:1 */
	175,	/* xmc2_3:1 */
	178,	/* xmc2_4:1 */
	181,	/* xmc2_5:1 */
	184,	/* xmc2_6:1 */
	187,	/* xmc2_7:1 */
	190,	/* xmc2_8:1 */
	193,	/* xmc2_9:1 */
	196,	/* xmc2_10:1 */
	199,	/* xmc2_11:1 */
	202,	/* xmc2_12:1 */
	222,	/* xmc3_0:1 */
	225,	/* xmc3_1:1 */
	228,	/* xmc3_2:1 */
	231,	/* xmc3_3:1 */
	234,	/* xmc3_4:1 */
	237,	/* xmc3_5:1 */
	240,	/* xmc3_6:1 */
	243,	/* xmc3_7:1 */
	246,	/* xmc3_8:1 */
	249,	/* xmc3_9:1 */
	252,	/* xmc3_10:1 */
	255,	/* xmc3_11:1 */
	258,	/* xmc3_12:1 */
	5,	/* LARc0:0 */
	10,	/* LARc1:1 */
	15,	/* LARc2:1 */
	28,	/* LARc5:1 */
	32,	/* LARc6:0 */
	34,	/* LARc7:1 */
	35,	/* LARc7:0 */
	16,	/* LARc2:0 */
	20,	/* LARc3:1 */
	21,	/* LARc3:0 */
	25,	/* LARc4:0 */
	52,	/* Xmaxc0:0 */
	108,	/* Xmaxc1:0 */
	164,	/* Xmaxc2:0 */
	220,	/* Xmaxc3:0 */
	55,	/* xmc0_0:0 */
	58,	/* xmc0_1:0 */
	61,	/* xmc0_2:0 */
	64,	/* xmc0_3:0 */
	67,	/* xmc0_4:0 */
	70,	/* xmc0_5:0 */
	73,	/* xmc0_6:0 */
	76,	/* xmc0_7:0 */
	79,	/* xmc0_8:0 */
	82,	/* xmc0_9:0 */
	85,	/* xmc0_10:0 */
	88,	/* xmc0_11:0 */
	91,	/* xmc0_12:0 */
	111,	/* xmc1_0:0 */
	114,	/* xmc1_1:0 */
	117,	/* xmc1_2:0 */
	120,	/* xmc1_3:0 */
	123,	/* xmc1_4:0 */
	126,	/* xmc1_5:0 */
	129,	/* xmc1_6:0 */
	132,	/* xmc1_7:0 */
	135,	/* xmc1_8:0 */
	138,	/* xmc1_9:0 */
	141,	/* xmc1_10:0 */
	144,	/* xmc1_11:0 */
	147,	/* xmc1_12:0 */
	167,	/* xmc2_0:0 */
	170,	/* xmc2_1:0 */
	173,	/* xmc2_2:0 */
	176,	/* xmc2_3:0 */
	179,	/* xmc2_4:0 */
	182,	/* xmc2_5:0 */
	185,	/* xmc2_6:0 */
	188,	/* xmc2_7:0 */
	191,	/* xmc2_8:0 */
	194,	/* xmc2_9:0 */
	197,	/* xmc2_10:0 */
	200,	/* xmc2_11:0 */
	203,	/* xmc2_12:0 */
	223,	/* xmc3_0:0 */
	226,	/* xmc3_1:0 */
	229,	/* xmc3_2:0 */
	232,	/* xmc3_3:0 */
	235,	/* xmc3_4:0 */
	238,	/* xmc3_5:0 */
	241,	/* xmc3_6:0 */
	244,	/* xmc3_7:0 */
	247,	/* xmc3_8:0 */
	250,	/* xmc3_9:0 */
	253,	/* xmc3_10:0 */
	256,	/* xmc3_11:0 */
	259,	/* xmc3_12:0 */
	11,	/* LARc1:0 */
	29,	/* LARc5:0 */
};

/*
 * Table 1 in section 6 of 3GPP TS 46.011 (substitution and muting of lost
 * frames) specifies a silence frame in the form of GSM 06.10 parameters;
 * the following const datum is this GSM 06.11 silence frame in GSM-FR
 * RTP encoding.
 */
const uint8_t osmo_gsm611_silence_frame[GSM_FR_BYTES] = {
	0xDA, 0xA7, 0xAA, 0xA5, 0x1A,
	0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B,
	0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B,
	0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B,
	0x50, 0x20, 0x38, 0xE4, 0x6D, 0xB9, 0x1B,
};

static const uint16_t sid_code_word_bits[95] = {
	/* bit numbers are relative to the RTP frame beginning,
	 * with signature bits included in the count. */
	57, 58, 60, 61, 63, 64, 66, 67, 69, 70, 72, 73,
	75, 76, 78, 79, 81, 82, 84, 85, 87, 88, 90, 91,
	93, 94, 113, 114, 116, 117, 119, 120, 122, 123,
	125, 126, 128, 129, 131, 132, 134, 135, 137,
	138, 140, 141, 143, 144, 146, 147, 149, 150,
	169, 170, 172, 173, 175, 176, 178, 179, 181,
	182, 184, 185, 187, 188, 190, 191, 193, 194,
	196, 197, 199, 200, 202, 203, 205, 206, 225,
	226, 228, 229, 231, 232, 234, 235, 237, 240,
	243, 246, 249, 252, 255, 258, 261
};

/*! Check whether RTP frame contains FR SID code word according to
 *  TS 101 318 §5.1.2
 *  \param[in] rtp_payload Buffer with RTP payload
 *  \param[in] payload_len Length of payload
 *  \returns true if code word is found, false otherwise
 */
bool osmo_fr_check_sid(const uint8_t *rtp_payload, size_t payload_len)
{
	struct bitvec bv;
	uint16_t i;

	/* signature does not match Full Rate SID */
	if ((rtp_payload[0] >> 4) != 0xD)
		return false;

	bv.data = (uint8_t *) rtp_payload;
	bv.data_len = payload_len;

	/* code word is all 0 at given bits */
	for (i = 0; i < ARRAY_SIZE(sid_code_word_bits); i++) {
		if (bitvec_get_bit_pos(&bv, sid_code_word_bits[i]) != ZERO)
			return false;
	}

	return true;
}

/*! Classify potentially-SID FR codec frame in RTP format according
 *  to the rules of GSM 06.31 §6.1.1
 *  \param[in] rtp_payload Buffer with RTP payload
 *  \returns enum osmo_gsm631_sid_class, with symbolic values
 *  OSMO_GSM631_SID_CLASS_SPEECH, OSMO_GSM631_SID_CLASS_INVALID or
 *  OSMO_GSM631_SID_CLASS_VALID corresponding to the 3 possible bit-counting
 *  classifications prescribed by the spec.
 *
 *  Differences between the more familiar osmo_fr_check_sid() and the present
 *  function are:
 *
 *  1. osmo_fr_check_sid() returns true only if the SID frame is absolutely
 *     perfect, with all 95 bits of the SID code word zeroed.  However, the
 *     rules of GSM 06.31 §6.1.1 allow up to one bit to be in error,
 *     and the frame is still accepted as valid SID.
 *
 *  2. The third possible state of invalid SID is not handled at all by the
 *     simpler osmo_fr_check_sid() function.
 *
 *  3. osmo_fr_check_sid() includes a check for 0xD RTP signature, and returns
 *     false if that signature nibble is wrong.  That check is not included
 *     in the present version because there is no place for it in the
 *     ETSI-prescribed classification, it is neither speech nor SID.  The
 *     assumption is that this function is used to classify the bit content
 *     of received codec frames, not their RTP encoding - the latter needs
 *     to be validated beforehand.
 *
 *  Which function should one use?  The answer depends on the specific
 *  circumstances, and needs to be addressed on a case-by-case basis.
 */
enum osmo_gsm631_sid_class osmo_fr_sid_classify(const uint8_t *rtp_payload)
{
	struct bitvec bv;
	uint16_t i, n;

	bv.data = (uint8_t *) rtp_payload;
	bv.data_len = GSM_FR_BYTES;

	/* count not-SID-matching bits per the spec */
	n = 0;
	for (i = 0; i < ARRAY_SIZE(sid_code_word_bits); i++) {
		if (bitvec_get_bit_pos(&bv, sid_code_word_bits[i]) != ZERO)
			n++;
		if (n >= 16)
			return OSMO_GSM631_SID_CLASS_SPEECH;
	}
	if (n >= 2)
		return OSMO_GSM631_SID_CLASS_INVALID;
	else
		return OSMO_GSM631_SID_CLASS_VALID;
}

/*! Reset the SID field and the unused bits of a potentially corrupted,
 *  but still valid GSM-FR SID frame in RTP encoding to their pristine state.
 *  \param[in] rtp_payload Buffer with RTP payload - must be writable!
 *
 *  Per GSM 06.12 section 5.2, a freshly minted SID frame carries 60 bits
 *  of comfort noise parameters (LARc and 4 times Xmaxc), while the remaining
 *  200 bits are all zeros; the latter 200 all-0 bits further break down into
 *  95 bits of SID field (checked by receivers to detect SID) and 105 unused
 *  bits which receivers are told to ignore.  Network elements that receive
 *  SID frames from call leg A uplink and need to retransmit them on leg B
 *  downlink should "rejuvenate" received SID frames prior to retransmission;
 *  this function does the job.
 */
void osmo_fr_sid_reset(uint8_t *rtp_payload)
{
	uint8_t *p, sub;

	p = rtp_payload + 5;	/* skip magic+LARc */
	for (sub = 0; sub < 4; sub++) {
		*p++ = 0;
		*p++ &= 0x1F;	/* upper 5 bits of Xmaxc field */
		*p++ &= 0x80;	/* and the lsb spilling into the next byte */
		*p++ = 0;
		*p++ = 0;
		*p++ = 0;
		*p++ = 0;
	}
}

/*! Preen potentially-SID FR codec frame in RTP format, ensuring that it is
 *  either a speech frame or a valid SID, and if the latter, making it a
 *  perfect, error-free SID frame.
 *  \param[in] rtp_payload Buffer with RTP payload - must be writable!
 *  \returns true if the frame is good, false otherwise
 */
bool osmo_fr_sid_preen(uint8_t *rtp_payload)
{
	enum osmo_gsm631_sid_class sidc;

	sidc = osmo_fr_sid_classify(rtp_payload);
	switch (sidc) {
	case OSMO_GSM631_SID_CLASS_SPEECH:
		return true;
	case OSMO_GSM631_SID_CLASS_INVALID:
		return false;
	case OSMO_GSM631_SID_CLASS_VALID:
		/* "Rejuvenate" this SID frame, correcting any errors */
		osmo_fr_sid_reset(rtp_payload);
		return true;
	default:
		/* There are only 3 possible SID classifications per GSM 06.31
		 * section 6.1.1, thus any other return value is a grave error
		 * in the code. */
		OSMO_ASSERT(0);
	}
}
