Review at  https://gerrit.osmocom.org/5062

Add functions for extended RACH coding

Add support for extended RACH (11 bit) according 3GPP TS 45.003 §5.3.2:

* convolutional code with puncturing
* encoding/decoding routines
* corresponding tests

Change-Id: I85a34a82d5cd39a594ee89d91a2338226066ab5d
Related: OS#1548
---
M include/osmocom/coding/gsm0503_coding.h
M src/coding/gsm0503_coding.c
M src/coding/libosmocoding.map
M src/gsm/libosmogsm.map
M tests/coding/coding_test.c
M tests/conv/conv_gsm0503_test.ok
M utils/conv_codes_gsm.py
7 files changed, 113 insertions(+), 5 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/62/5062/1

diff --git a/include/osmocom/coding/gsm0503_coding.h 
b/include/osmocom/coding/gsm0503_coding.h
index a2d4115..39b701f 100644
--- a/include/osmocom/coding/gsm0503_coding.h
+++ b/include/osmocom/coding/gsm0503_coding.h
@@ -63,6 +63,9 @@
        int codec_mode_req, uint8_t *codec, int codecs, uint8_t *ft,
        uint8_t *cmr, int *n_errors, int *n_bits_total);
 
+int gsm0503_rach_ext_encode(ubit_t *burst, uint16_t ra, uint8_t bsic);
+int gsm0503_rach_ext_decode(uint16_t *ra, const sbit_t *burst, uint8_t bsic);
+
 int gsm0503_rach_encode(ubit_t *burst, const uint8_t *ra, uint8_t bsic);
 int gsm0503_rach_decode(uint8_t *ra, const sbit_t *burst, uint8_t bsic);
 
diff --git a/src/coding/gsm0503_coding.c b/src/coding/gsm0503_coding.c
index 5213dc5..59701d4 100644
--- a/src/coding/gsm0503_coding.c
+++ b/src/coding/gsm0503_coding.c
@@ -2822,13 +2822,60 @@
  * b(0) = MSB of PLMN colour code
  * b(5) = LSB of BS colour code
  */
-static int rach_apply_bsic(ubit_t *d, uint8_t bsic)
+static inline void rach_apply_bsic(ubit_t *d, uint8_t bsic, uint8_t start)
 {
        int i;
 
        /* Apply it */
        for (i = 0; i < 6; i++)
-               d[8 + i] ^= ((bsic >> (5 - i)) & 1);
+               d[start + i] ^= ((bsic >> (5 - i)) & 1);
+}
+
+/*! Decode the Extended (11-bit) RACH according to 3GPP TS 45.003
+ *  \param[out] ra output buffer for RACH data
+ *  \param[in] burst Input burst data
+ *  \param[in] bsic BSIC used in this cell
+ *  \returns 0 on success; negative on error (e.g. CRC error) */
+int gsm0503_rach_ext_decode(uint16_t *ra11, const sbit_t *burst, uint8_t bsic)
+{
+       ubit_t conv[17];
+       uint8_t ra[2];
+       int rv;
+
+       osmo_conv_decode(&gsm0503_ext_rach, burst, conv);
+
+       rach_apply_bsic(conv, bsic, 11);
+
+       rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 11, conv + 11);
+       if (rv)
+               return -1;
+
+       osmo_ubit2pbit_ext(ra, 0, conv, 0, 11, 1);
+
+       *ra11 = osmo_load16le(ra);
+
+       return 0;
+}
+
+/*! Encode the Extended (11-bit) RACH according to 3GPP TS 45.003
+ *  \param[out] burst Caller-allocated output burst buffer
+ *  \param[in] ra Input RACH data
+ *  \param[in] bsic BSIC used in this cell
+ *  \returns 0 on success; negative on error */
+int gsm0503_rach_ext_encode(ubit_t *burst, uint16_t ra11, uint8_t bsic)
+{
+       ubit_t conv[17];
+       uint8_t ra[2];
+
+       osmo_store16le(ra11, ra);
+
+       osmo_pbit2ubit_ext(conv, 0, ra, 0, 11, 1);
+
+       osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 11, conv + 11);
+
+       rach_apply_bsic(conv, bsic, 11);
+
+       osmo_conv_encode(&gsm0503_ext_rach, conv, burst);
 
        return 0;
 }
@@ -2845,7 +2892,7 @@
 
        osmo_conv_decode(&gsm0503_rach, burst, conv);
 
-       rach_apply_bsic(conv, bsic);
+       rach_apply_bsic(conv, bsic, 8);
 
        rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 8, conv + 8);
        if (rv)
@@ -2869,7 +2916,7 @@
 
        osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 8, conv + 8);
 
-       rach_apply_bsic(conv, bsic);
+       rach_apply_bsic(conv, bsic, 8);
 
        osmo_conv_encode(&gsm0503_rach, conv, burst);
 
diff --git a/src/coding/libosmocoding.map b/src/coding/libosmocoding.map
index dbb53de..95953cf 100644
--- a/src/coding/libosmocoding.map
+++ b/src/coding/libosmocoding.map
@@ -108,6 +108,8 @@
 gsm0503_tch_afs_decode;
 gsm0503_tch_ahs_encode;
 gsm0503_tch_ahs_decode;
+gsm0503_rach_ext_encode;
+gsm0503_rach_ext_decode;
 gsm0503_rach_encode;
 gsm0503_rach_decode;
 gsm0503_sch_encode;
diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map
index a72db52..51cd9b3 100644
--- a/src/gsm/libosmogsm.map
+++ b/src/gsm/libosmogsm.map
@@ -97,6 +97,7 @@
 
 gsm0503_xcch;
 gsm0503_rach;
+gsm0503_ext_rach;
 gsm0503_sch;
 gsm0503_cs2;
 gsm0503_cs3;
diff --git a/tests/coding/coding_test.c b/tests/coding/coding_test.c
index 9a00f0d..e6b25be 100644
--- a/tests/coding/coding_test.c
+++ b/tests/coding/coding_test.c
@@ -150,6 +150,38 @@
        printd("\n");
 }
 
+static void test_rach_ext(uint8_t bsic, uint16_t ra)
+{
+       uint16_t result;
+       ubit_t bursts_u[36];
+       sbit_t bursts_s[36];
+
+       /* Encode L2 message */
+       printd("Encoding: %02x\n", ra);
+       gsm0503_rach_ext_encode(bursts_u, ra, bsic);
+
+       /* Prepare soft-bits */
+       ubits2sbits(bursts_u, bursts_s, 36);
+
+       printd("U-Bits:\n");
+       printd("%s\n", osmo_hexdump(bursts_u, 36));
+
+       printd("S-Bits:\n");
+       printd("%s\n", osmo_hexdump((uint8_t *)bursts_s, 36));
+
+       /* Destroy some bits */
+       memset(bursts_s + 9, 0, 8);
+
+       /* Decode, correcting errors */
+       gsm0503_rach_ext_decode(&result, bursts_s, bsic);
+       printd("Decoded: %02x\n", result);
+
+       if (ra != result)
+               printf("FAIL [RACH ext]: encoded %u != %u decoded\n", ra, 
result);
+
+       printd("\n");
+}
+
 static void test_sch(uint8_t *info)
 {
        uint8_t result[4];
@@ -464,6 +496,12 @@
                test_rach(0x1a, i);
        }
 
+       for (i = 0; i < 2048; i++) {
+               test_rach_ext(0x3f, i);
+               test_rach_ext(0x00, i);
+               test_rach_ext(0x1a, i);
+       }
+
        for (i = 0; i < len_l2; i++)
                test_sch(test_l2[i]);
 
diff --git a/tests/conv/conv_gsm0503_test.ok b/tests/conv/conv_gsm0503_test.ok
index e6e2572..ad618a8 100644
--- a/tests/conv/conv_gsm0503_test.ok
+++ b/tests/conv/conv_gsm0503_test.ok
@@ -14,6 +14,14 @@
 [..] Encoding / Decoding cycle : OK
 [..] Encoding / Decoding cycle : OK
 
+[+] Testing: gsm0503_ext_rach
+[.] Input length  : ret =  17  exp =  17 -> OK
+[.] Output length : ret =  36  exp =  36 -> OK
+[.] Random vector checks:
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+[..] Encoding / Decoding cycle : OK
+
 [+] Testing: gsm0503_sch
 [.] Input length  : ret =  35  exp =  35 -> OK
 [.] Output length : ret =  78  exp =  78 -> OK
diff --git a/utils/conv_codes_gsm.py b/utils/conv_codes_gsm.py
index 279bd3a..77b9ece 100644
--- a/utils/conv_codes_gsm.py
+++ b/utils/conv_codes_gsm.py
@@ -1,5 +1,5 @@
 #!/usr/bin/python2
-
+# -*- coding: utf-8 -*-
 from conv_gen import ConvolutionalCode
 from conv_gen import poly
 
@@ -49,6 +49,15 @@
                description = ["RACH convolutional code"]
        ),
 
+        # Extended RACH definition from 3GPP TS 45.003 §5.3.2
+       ConvolutionalCode(
+               17,
+               shared_polys["xcch"],
+                puncture = [ 0, 2, 5, 37, 39, 41, -1 ],
+               name = "ext_rach",
+               description = ["Extended RACH (11 bit) convolutional code"]
+       ),
+
        # SCH definition
        ConvolutionalCode(
                35,

-- 
To view, visit https://gerrit.osmocom.org/5062
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I85a34a82d5cd39a594ee89d91a2338226066ab5d
Gerrit-PatchSet: 1
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: Max <[email protected]>

Reply via email to