diff options
Diffstat (limited to 'src/osmo-bts-trx/gsm0503_interleaving.c')
-rw-r--r-- | src/osmo-bts-trx/gsm0503_interleaving.c | 413 |
1 files changed, 412 insertions, 1 deletions
diff --git a/src/osmo-bts-trx/gsm0503_interleaving.c b/src/osmo-bts-trx/gsm0503_interleaving.c index ec47a6b3..4569cfa2 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,416 @@ 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]; + + 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 * |