aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-trx/gsm0503_interleaving.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bts-trx/gsm0503_interleaving.c')
-rw-r--r--src/osmo-bts-trx/gsm0503_interleaving.c376
1 files changed, 375 insertions, 1 deletions
diff --git a/src/osmo-bts-trx/gsm0503_interleaving.c b/src/osmo-bts-trx/gsm0503_interleaving.c
index ec47a6b..b651556 100644
--- a/src/osmo-bts-trx/gsm0503_interleaving.c
+++ b/src/osmo-bts-trx/gsm0503_interleaving.c
@@ -1,5 +1,6 @@
#include <stdint.h>
+#include <string.h>
#include <osmocom/core/bits.h>
@@ -28,7 +29,7 @@
* Where hl(B) and hn(B) are bits in burst B indicating flags.
*/
-void gsm0503_xcch_deinterleave(sbit_t *cB, sbit_t *iB)
+void gsm0503_xcch_deinterleave(sbit_t *cB, const sbit_t *iB)
{
int j, k, B;
@@ -50,6 +51,379 @@ void gsm0503_xcch_interleave(ubit_t *cB, ubit_t *iB)
}
}
+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];
+
+ for (k=0; k<12; k++)
+ u[k] = c[k];
+ for (k=12; k<80; k++)
+ hc[k - 12] = c[k];
+ for (k=80; k<452; k++)
+ dc[k - 80] = c[k];
+}
+
+void gsm0503_mcs1_dl_interleave(const ubit_t *u, 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] = u[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];
+
+ for (k=0; k<80; k++)
+ hc[k] = c[k];
+ 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 */
+ for (k=0; k<136; k++) {
+ j = 34 * (k % 4) + 2 * (11 * k % 17) + k % 8 / 4;
+ hc[k] = hi[j];
+ }
+
+ /* Data */
+ 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 */
+ for (k=0; k<100; k++) {
+ j = 25 * (k % 4) + ((17 * k) % 25);
+ hc[k] = hi[j];
+ }
+
+ /* Data */
+ 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 */
+ for (k=0; k<124; k++) {
+ j = 31 * (k % 4) + ((17 * k) % 31);
+ hc[k] = hi[j];
+ }
+
+ /* Data */
+ 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 */
+ for (k=0; k<160; k++) {
+ j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+ hc[k] = hi[j];
+ }
+
+ /* Data */
+ 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 */
+ for (k=0; k<160; k++) {
+ j = 40 * (k % 4) + 2 * (13 * (k / 8) % 20) + k % 8 / 4;
+ hc[k] = hi[j];
+ }
+
+ /* 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;
+ 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 */
+ for (k=0; k<124; k++) {
+ j = 31 * (k % 4) + ((17 * k) % 31);
+ hc[k] = hi[j];
+ }
+
+ /* 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;
+ dc[k] = di[j];
+ }
+
+ memcpy(c1, &dc[0], 612);
+ memcpy(c2, &dc[612], 612);
+}
+
/*
* GSM TCH FR/EFR/AFS interleaving and burst mapping
*