libosmocoding: migrate transcoding routines from OsmoBTS

There are some projects, such as GR-GSM and OsmocomBB, which would
benefit from using one shared implementation of GSM 05.03 code. So,
this commit introduces a new sub-library called libosmocoding, which
(for now) provides GSM, GPRS and EDGE transcoding routines, migrated
from OsmoBTS.

The original GSM 05.03 code from OsmoBTS was relicensed under
GPLv2-or-later with permission of copyright holders (Andreas Eversberg,
Alexander Chemeris and Tom Tsou).

The following data types are currently supported:

 - xCCH
 - PDTCH (CS 1-4 and MCS 1-9)
 - TCH/FR
 - TCH/HR
 - TCH/AFS
 - RCH/AHS
 - RACH
 - SCH

Change-Id: I0c3256b87686d878e4e716d12393cad5924fdfa1
diff --git a/src/coding/gsm0503_interleaving.c b/src/coding/gsm0503_interleaving.c
new file mode 100644
index 0000000..22ad6f6
--- /dev/null
+++ b/src/coding/gsm0503_interleaving.c
@@ -0,0 +1,573 @@
+/*
+ * (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_tables.h>
+#include <osmocom/coding/gsm0503_interleaving.h>
+
+/*
+ * GSM xCCH interleaving and burst mapping
+ *
+ * Interleaving:
+ *
+ * Given 456 coded input bits, form 4 blocks of 114 bits:
+ *
+ *      i(B, j) = c(n, k)       k = 0, ..., 455
+ *                              n = 0, ..., N, N + 1, ...
+ *                              B = B_0 + 4n + (k mod 4)
+ *                              j = 2(49k mod 57) + ((k mod 8) div 4)
+ *
+ * Mapping on Burst:
+ *
+ *      e(B, j) = i(B, j)
+ *      e(B, 59 + j) = i(B, 57 + j)     j = 0, ..., 56
+ *      e(B, 57) = h_l(B)
+ *      e(B, 58) = h_n(B)
+ *
+ * Where hl(B) and hn(B) are bits in burst B indicating flags.
+ */
+
+void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB)
+{
+	int j, k, B;
+
+	for (k = 0; k < 456; k++) {
+		B = k & 3;
+		j = 2 * ((49 * k) % 57) + ((k & 7) >> 2);
+		cB[k] = iB[B * 114 + j];
+	}
+}
+
+void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB)
+{
+	int j, k, B;
+
+	for (k = 0; k < 456; k++) {
+		B = k & 3;
+		j = 2 * ((49 * k) % 57) + ((k & 7) >> 2);
+		iB[B * 114 + j] = cB[k];
+	}
+}
+
+void gsm0503_mcs1_dl_deinterleave(sbit_t *u, sbit_t *hc,
+	sbit_t *dc, const sbit_t *iB)
+{
+	int k;
+	sbit_t c[452];
+	sbit_t cp[456];
+
+	gsm0503_xcch_deinterleave(cp, iB);
+
+	for (k = 0; k < 25; k++)
+		c[k] = cp[k];
+	for (k = 26; k < 82; k++)
+		c[k - 1] = cp[k];
+	for (k = 83; k < 139; k++)
+		c[k - 2] = cp[k];
+	for (k = 140; k < 424; k++)
+		c[k - 3] = cp[k];
+	for (k = 425; k < 456; k++)
+		c[k - 4] = cp[k];
+
+	if (u) {
+		for (k = 0; k < 12; k++)
+			u[k] = c[k];
+	}
+
+	if (hc) {
+		for (k = 12; k < 80; k++)
+			hc[k - 12] = c[k];
+	}
+
+	if (dc) {
+		for (k = 80; k < 452; k++)
+			dc[k - 80] = c[k];
+	}
+}
+
+void gsm0503_mcs1_dl_interleave(const ubit_t *up, const ubit_t *hc,
+	const ubit_t *dc, ubit_t *iB)
+{
+	int k;
+	ubit_t c[452];
+	ubit_t cp[456];
+
+	for (k = 0; k < 12; k++)
+		c[k] = up[k];
+	for (k = 12; k < 80; k++)
+		c[k] = hc[k - 12];
+	for (k = 80; k < 452; k++)
+		c[k] = dc[k - 80];
+
+	for (k = 0; k < 25; k++)
+		cp[k] = c[k];
+	for (k = 26; k < 82; k++)
+		cp[k] = c[k - 1];
+	for (k = 83; k < 139; k++)
+		cp[k] = c[k - 2];
+	for (k = 140; k < 424; k++)
+		cp[k] = c[k - 3];
+	for (k = 425; k < 456; k++)
+		cp[k] = c[k - 4];
+
+	cp[25] = 0;
+	cp[82] = 0;
+	cp[139] = 0;
+	cp[424] = 0;
+
+	gsm0503_xcch_interleave(cp, iB);
+}
+
+void gsm0503_mcs1_ul_deinterleave(sbit_t *hc, sbit_t *dc, const sbit_t *iB)
+{
+	int k;
+	sbit_t c[452];
+	sbit_t cp[456];
+
+	gsm0503_xcch_deinterleave(cp, iB);
+
+	for (k = 0; k < 25; k++)
+		c[k] = cp[k];
+	for (k = 26; k < 82; k++)
+		c[k - 1] = cp[k];
+	for (k = 83; k < 139; k++)
+		c[k - 2] = cp[k];
+	for (k = 140; k < 424; k++)
+		c[k - 3] = cp[k];
+	for (k = 425; k < 456; k++)
+		c[k - 4] = cp[k];
+
+	if (hc) {
+		for (k = 0; k < 80; k++)
+			hc[k] = c[k];
+	}
+
+	if (dc) {
+		for (k = 80; k < 452; k++)
+			dc[k - 80] = c[k];
+	}
+}
+
+void gsm0503_mcs1_ul_interleave(const ubit_t *hc, const ubit_t *dc, ubit_t *iB)
+{
+	int k;
+	ubit_t c[452];
+	ubit_t cp[456];
+
+	for (k = 0; k < 80; k++)
+		c[k] = hc[k];
+	for (k = 80; k < 452; k++)
+		c[k] = dc[k - 80];
+
+	for (k = 0; k < 25; k++)
+		cp[k] = c[k];
+	for (k = 26; k < 82; k++)
+		cp[k] = c[k - 1];
+	for (k = 83; k < 139; k++)
+		cp[k] = c[k - 2];
+	for (k = 140; k < 424; k++)
+		cp[k] = c[k - 3];
+	for (k = 425; k < 456; k++)
+		cp[k] = c[k - 4];
+
+	cp[25] = 0;
+	cp[82] = 0;
+	cp[139] = 0;
+	cp[424] = 0;
+
+	gsm0503_xcch_interleave(cp, iB);
+}
+
+void gsm0503_mcs5_ul_interleave(const ubit_t *hc, const ubit_t *dc,
+	ubit_t *hi, ubit_t *di)
+{
+	int j, k;
+
+	/* Header */
+	for (k = 0; k < 136; k++) {
+		j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4;
+		hi[j] = hc[k];
+	}
+
+	/* Data */
+	for (k = 0; k < 1248; k++) {
+		j = gsm0503_interleave_mcs5[k];
+		di[j] = dc[k];
+	}
+}
+
+void gsm0503_mcs5_ul_deinterleave(sbit_t *hc, sbit_t *dc,
+	const sbit_t *hi, const sbit_t *di)
+{
+	int j, k;
+
+	/* Header */
+	if (hc) {
+		for (k = 0; k < 136; k++) {
+			j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4;
+			hc[k] = hi[j];
+		}
+	}
+
+	/* Data */
+	if (dc) {
+		for (k = 0; k < 1248; k++) {
+			j = gsm0503_interleave_mcs5[k];
+			dc[k] = di[j];
+		}
+	}
+}
+
+void gsm0503_mcs5_dl_interleave(const ubit_t *hc, const ubit_t *dc,
+	ubit_t *hi, ubit_t *di)
+{
+	int j, k;
+
+	/* Header */
+	for (k = 0; k < 100; k++) {
+		j = 25 * (k % 4) + ((17 * k) % 25);
+		hi[j] = hc[k];
+	}
+
+	/* Data */
+	for (k = 0; k < 1248; k++) {
+		j = gsm0503_interleave_mcs5[k];
+		di[j] = dc[k];
+	}
+}
+
+void gsm0503_mcs5_dl_deinterleave(sbit_t *hc, sbit_t *dc,
+	const sbit_t *hi, const sbit_t *di)
+{
+	int j, k;
+
+	/* Header */
+	if (hc) {
+		for (k = 0; k < 100; k++) {
+			j = 25 * (k % 4) + ((17 * k) % 25);
+			hc[k] = hi[j];
+		}
+	}
+
+	/* Data */
+	if (dc) {
+		for (k = 0; k < 1248; k++) {
+			j = gsm0503_interleave_mcs5[k];
+			dc[k] = di[j];
+		}
+	}
+}
+
+void gsm0503_mcs7_dl_interleave(const ubit_t *hc, const ubit_t *c1,
+	const ubit_t *c2, ubit_t *hi, ubit_t *di)
+{
+	int j, k;
+	ubit_t dc[1224];
+
+	/* Header */
+	for (k = 0; k < 124; k++) {
+		j = 31 * (k % 4) + ((17 * k) % 31);
+		hi[j] = hc[k];
+	}
+
+	memcpy(&dc[0], c1, 612);
+	memcpy(&dc[612], c2, 612);
+
+	/* Data */
+	for (k = 0; k < 1224; k++) {
+		j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) +
+			(k + 2 - k / 408) % 3;
+		di[j] = dc[k];
+	}
+}
+
+
+void gsm0503_mcs7_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+	const sbit_t *hi, const sbit_t *di)
+{
+	int j, k;
+	ubit_t dc[1224];
+
+	/* Header */
+	if (hc) {
+		for (k = 0; k < 124; k++) {
+			j = 31 * (k % 4) + ((17 * k) % 31);
+			hc[k] = hi[j];
+		}
+	}
+
+	/* Data */
+	if (c1 && c2) {
+		for (k = 0; k < 1224; k++) {
+			j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) +
+	(k + 2 - k / 408) % 3;
+			dc[k] = di[j];
+		}
+
+		memcpy(c1, &dc[0], 612);
+		memcpy(c2, &dc[612], 612);
+	}
+}
+
+void gsm0503_mcs7_ul_interleave(const ubit_t *hc, const ubit_t *c1,
+	const ubit_t *c2, ubit_t *hi, ubit_t *di)
+{
+	int j, k;
+	ubit_t dc[1224];
+
+	/* Header */
+	for (k = 0; k < 160; k++) {
+		j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+		hi[j] = hc[k];
+	}
+
+	memcpy(&dc[0], c1, 612);
+	memcpy(&dc[612], c2, 612);
+
+	/* Data */
+	for (k = 0; k < 1224; k++) {
+		j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) +
+			(k + 2 - k / 408) % 3;
+		di[j] = dc[k];
+	}
+}
+
+void gsm0503_mcs7_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+	const sbit_t *hi, const sbit_t *di)
+{
+	int j, k;
+	ubit_t dc[1224];
+
+	/* Header */
+	if (hc) {
+		for (k = 0; k < 160; k++) {
+			j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+			hc[k] = hi[j];
+		}
+	}
+
+	/* Data */
+	if (c1 && c2) {
+		for (k = 0; k < 1224; k++) {
+			j = 306 * (k % 4) + 3 * (44 * k % 102 + k / 4 % 2) +
+	(k + 2 - k / 408) % 3;
+			dc[k] = di[j];
+		}
+
+		memcpy(c1, &dc[0], 612);
+		memcpy(c2, &dc[612], 612);
+	}
+}
+
+void gsm0503_mcs8_ul_interleave(const ubit_t *hc, const ubit_t *c1,
+	const ubit_t *c2, ubit_t *hi, ubit_t *di)
+{
+	int j, k;
+	ubit_t dc[1224];
+
+	/* Header */
+	for (k = 0; k < 160; k++) {
+		j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+		hi[j] = hc[k];
+	}
+
+	memcpy(&dc[0], c1, 612);
+	memcpy(&dc[612], c2, 612);
+
+	/* Data */
+	for (k = 0; k < 1224; k++) {
+		j = 306 * (2 * (k / 612) + (k % 2)) +
+			3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3;
+		di[j] = dc[k];
+	}
+}
+
+void gsm0503_mcs8_ul_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+	const sbit_t *hi, const sbit_t *di)
+{
+	int j, k;
+	ubit_t dc[1224];
+
+	/* Header */
+	if (hc) {
+		for (k = 0; k < 160; k++) {
+			j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+			hc[k] = hi[j];
+		}
+	}
+
+	/* Data */
+	if (c1 && c2) {
+		for (k = 0; k < 1224; k++) {
+			j = 306 * (2 * (k / 612) + (k % 2)) +
+	3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3;
+			dc[k] = di[j];
+		}
+
+		memcpy(c1, &dc[0], 612);
+		memcpy(c2, &dc[612], 612);
+	}
+}
+
+void gsm0503_mcs8_dl_interleave(const ubit_t *hc, const ubit_t *c1,
+	const ubit_t *c2, ubit_t *hi, ubit_t *di)
+{
+	int j, k;
+	ubit_t dc[1224];
+
+	/* Header */
+	for (k = 0; k < 124; k++) {
+		j = 31 * (k % 4) + ((17 * k) % 31);
+		hi[j] = hc[k];
+	}
+
+	memcpy(&dc[0], c1, 612);
+	memcpy(&dc[612], c2, 612);
+
+	/* Data */
+	for (k = 0; k < 1224; k++) {
+		j = 306 * (2 * (k / 612) + (k % 2)) +
+			3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3;
+		di[j] = dc[k];
+	}
+}
+
+void gsm0503_mcs8_dl_deinterleave(sbit_t *hc, sbit_t *c1, sbit_t *c2,
+	const sbit_t *hi, const sbit_t *di)
+{
+	int j, k;
+	ubit_t dc[1224];
+
+	/* Header */
+	if (hc) {
+		for (k = 0; k < 124; k++) {
+			j = 31 * (k % 4) + ((17 * k) % 31);
+			hc[k] = hi[j];
+		}
+	}
+
+	/* Data */
+	if (c1 && c2) {
+		for (k = 0; k < 1224; k++) {
+			j = 306 * (2 * (k / 612) + (k % 2)) +
+	3 * (74 * k % 102 + k / 2 % 2) + (k + 2 - k / 204) % 3;
+			dc[k] = di[j];
+		}
+
+		memcpy(c1, &dc[0], 612);
+		memcpy(c2, &dc[612], 612);
+	}
+}
+
+/*
+ * GSM TCH FR/EFR/AFS interleaving and burst mapping
+ *
+ * Interleaving:
+ *
+ * Given 456 coded input bits, form 8 blocks of 114 bits,
+ * where even bits of the first 4 blocks and odd bits of the last 4 blocks
+ * are used:
+ *
+ *      i(B, j) = c(n, k)       k = 0, ..., 455
+ *                              n = 0, ..., N, N + 1, ...
+ *                              B = B_0 + 4n + (k mod 8)
+ *                              j = 2(49k mod 57) + ((k mod 8) div 4)
+ *
+ * Mapping on Burst:
+ *
+ *      e(B, j) = i(B, j)
+ *      e(B, 59 + j) = i(B, 57 + j)     j = 0, ..., 56
+ *      e(B, 57) = h_l(B)
+ *      e(B, 58) = h_n(B)
+ *
+ * Where hl(B) and hn(B) are bits in burst B indicating flags.
+ */
+
+void gsm0503_tch_fr_deinterleave(sbit_t *cB, sbit_t *iB)
+{
+	int j, k, B;
+
+	for (k = 0; k < 456; k++) {
+		B = k & 7;
+		j = 2 * ((49 * k) % 57) + ((k & 7) >> 2);
+		cB[k] = iB[B * 114 + j];
+	}
+}
+
+void gsm0503_tch_fr_interleave(ubit_t *cB, ubit_t *iB)
+{
+	int j, k, B;
+
+	for (k = 0; k < 456; k++) {
+		B = k & 7;
+		j = 2 * ((49 * k) % 57) + ((k & 7) >> 2);
+		iB[B * 114 + j] = cB[k];
+	}
+}
+
+/*
+ * GSM TCH HR/AHS interleaving and burst mapping
+ *
+ * Interleaving:
+ *
+ * Given 288 coded input bits, form 4 blocks of 114 bits,
+ * where even bits of the first 2 blocks and odd bits of the last 2 blocks
+ * are used:
+ *
+ *      i(B, j) = c(n, k)       k = 0, ..., 227
+ *                              n = 0, ..., N, N + 1, ...
+ *                              B = B_0 + 2n + b
+ *                              j, b = table[k];
+ *
+ * Mapping on Burst:
+ *
+ *      e(B, j) = i(B, j)
+ *      e(B, 59 + j) = i(B, 57 + j)     j = 0, ..., 56
+ *      e(B, 57) = h_l(B)
+ *      e(B, 58) = h_n(B)
+ *
+ * Where hl(B) and hn(B) are bits in burst B indicating flags.
+ */
+
+void gsm0503_tch_hr_deinterleave(sbit_t *cB, sbit_t *iB)
+{
+	int j, k, B;
+
+	for (k = 0; k < 228; k++) {
+		B = gsm0503_tch_hr_interleaving[k][1];
+		j = gsm0503_tch_hr_interleaving[k][0];
+		cB[k] = iB[B * 114 + j];
+	}
+}
+
+void gsm0503_tch_hr_interleave(ubit_t *cB, ubit_t *iB)
+{
+	int j, k, B;
+
+	for (k = 0; k < 228; k++) {
+		B = gsm0503_tch_hr_interleaving[k][1];
+		j = gsm0503_tch_hr_interleaving[k][0];
+		iB[B * 114 + j] = cB[k];
+	}
+}