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
This commit is contained in:
Max 2017-10-16 14:58:00 +02:00
parent 9dd3bf0cb4
commit 32e5641dbb
9 changed files with 30850 additions and 21 deletions

View File

@ -8,3 +8,4 @@
# If any interfaces have been removed or changed since the last public release: c:r:0.
#library what description / commit summary line
core msgb_queue_free() add inline func to msgb.h
coding gsm0503_rach_ext-encode() add func to gsm0503_coding.h

View File

@ -5,6 +5,8 @@
#pragma once
#include <stdint.h>
#include <osmocom/core/defs.h>
#include <osmocom/core/bits.h>
/*! \addtogroup coding
@ -63,8 +65,11 @@ int gsm0503_tch_ahs_decode(uint8_t *tch_data, const sbit_t *bursts, int odd,
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_encode(ubit_t *burst, const uint8_t *ra, uint8_t bsic);
int gsm0503_rach_ext_encode(ubit_t *burst, uint16_t ra, uint8_t bsic, bool is_11bit);
int gsm0503_rach_encode(ubit_t *burst, const uint8_t *ra, uint8_t bsic) OSMO_DEPRECATED("Use gsm0503_rach_ext_encode() instead");
int gsm0503_rach_decode(uint8_t *ra, const sbit_t *burst, uint8_t bsic);
int gsm0503_rach_ext_decode(uint16_t *ra, const sbit_t *burst, uint8_t bsic);
int gsm0503_sch_encode(ubit_t *burst, const uint8_t *sb_info);
int gsm0503_sch_decode(uint8_t *sb_info, const sbit_t *burst);

View File

@ -2824,13 +2824,47 @@ invalid_length:
* 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);
}
static inline int16_t rach_decode(const sbit_t *burst, uint8_t bsic, bool is_11bit)
{
ubit_t conv[17];
uint8_t ra[2] = { 0 }, nbits = is_11bit ? 11 : 8;
int rv;
osmo_conv_decode(is_11bit ? &gsm0503_rach_ext : &gsm0503_rach, burst, conv);
rach_apply_bsic(conv, bsic, nbits);
rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, nbits, conv + nbits);
if (rv)
return -1;
osmo_ubit2pbit_ext(ra, 0, conv, 0, nbits, 1);
return is_11bit ? osmo_load16le(ra) : ra[0];
}
/*! 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 *ra, const sbit_t *burst, uint8_t bsic)
{
int16_t r = rach_decode(burst, bsic, true);
if (r < 0)
return r;
*ra = r;
return 0;
}
@ -2842,18 +2876,12 @@ static int rach_apply_bsic(ubit_t *d, uint8_t bsic)
* \returns 0 on success; negative on error (e.g. CRC error) */
int gsm0503_rach_decode(uint8_t *ra, const sbit_t *burst, uint8_t bsic)
{
ubit_t conv[14];
int rv;
int16_t r = rach_decode(burst, bsic, false);
osmo_conv_decode(&gsm0503_rach, burst, conv);
if (r < 0)
return r;
rach_apply_bsic(conv, bsic);
rv = osmo_crc8gen_check_bits(&gsm0503_rach_crc6, conv, 8, conv + 8);
if (rv)
return -1;
osmo_ubit2pbit_ext(ra, 0, conv, 0, 8, 1);
*ra = r;
return 0;
}
@ -2865,15 +2893,33 @@ int gsm0503_rach_decode(uint8_t *ra, const sbit_t *burst, uint8_t bsic)
* \returns 0 on success; negative on error */
int gsm0503_rach_encode(ubit_t *burst, const uint8_t *ra, uint8_t bsic)
{
ubit_t conv[14];
return gsm0503_rach_ext_encode(burst, *ra, bsic, false);
}
osmo_pbit2ubit_ext(conv, 0, ra, 0, 8, 1);
/*! Encode the Extended (11-bit) or regular (8-bit) RACH according to 3GPP TS 45.003
* \param[out] burst Caller-allocated output burst buffer
* \param[in] ra11 Input RACH data
* \param[in] bsic BSIC used in this cell
* \param[in] is_11bit whether given RA is 11 bit or not
* \returns 0 on success; negative on error */
int gsm0503_rach_ext_encode(ubit_t *burst, uint16_t ra11, uint8_t bsic, bool is_11bit)
{
ubit_t conv[17];
uint8_t ra[2] = { 0 }, nbits = 8;
osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, 8, conv + 8);
if (is_11bit) {
osmo_store16le(ra11, ra);
nbits = 11;
} else
ra[0] = (uint8_t)ra11;
rach_apply_bsic(conv, bsic);
osmo_pbit2ubit_ext(conv, 0, ra, 0, nbits, 1);
osmo_conv_encode(&gsm0503_rach, conv, burst);
osmo_crc8gen_set_bits(&gsm0503_rach_crc6, conv, nbits, conv + nbits);
rach_apply_bsic(conv, bsic, nbits);
osmo_conv_encode(is_11bit ? &gsm0503_rach_ext : &gsm0503_rach, conv, burst);
return 0;
}

View File

@ -108,6 +108,8 @@ gsm0503_tch_afs_encode;
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;

View File

@ -97,6 +97,7 @@ gsm0502_calc_paging_group;
gsm0503_xcch;
gsm0503_rach;
gsm0503_rach_ext;
gsm0503_sch;
gsm0503_cs2;
gsm0503_cs3;

View File

@ -110,7 +110,7 @@ static void test_rach(uint8_t bsic, uint8_t ra)
/* Encode L2 message */
printf("Encoding: %02x\n", ra);
gsm0503_rach_encode(bursts_u, &ra, bsic);
gsm0503_rach_ext_encode(bursts_u, ra, bsic, false);
/* Prepare soft-bits */
osmo_ubit2sbit(bursts_s, bursts_u, 36);
@ -126,7 +126,38 @@ static void test_rach(uint8_t bsic, uint8_t ra)
gsm0503_rach_decode(&result, bursts_s, bsic);
printf("Decoded: %02x\n", result);
OSMO_ASSERT(ra == result);
if (ra != result)
printf("FAIL [RACH]: encoded %u != %u decoded\n", ra, result);
printf("\n");
}
static void test_rach_ext(uint8_t bsic, uint16_t ra)
{
uint16_t result = 3000; /* Max ext. RA is 2^11 = 2048 */
ubit_t bursts_u[36];
sbit_t bursts_s[36];
/* Encode L2 message */
printf("Encoding: %02x\n", ra);
gsm0503_rach_ext_encode(bursts_u, ra, bsic, true);
/* Prepare soft-bits */
osmo_ubit2sbit(bursts_s, bursts_u, 36);
printf("U-Bits: %s\n", osmo_ubit_dump(bursts_u, 36));
printf("S-Bits: %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);
printf("Decoded: %02x\n", result);
if (ra != result)
printf("FAIL [RACH ext]: encoded %u != %u decoded\n", ra, result);
printf("\n");
}
@ -332,6 +363,12 @@ int main(int argc, char **argv)
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]);

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,14 @@
[..] Encoding / Decoding cycle : OK
[..] Encoding / Decoding cycle : OK
[+] Testing: gsm0503_rach_ext
[.] 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

View File

@ -1,5 +1,5 @@
#!/usr/bin/python2
# -*- coding: utf-8 -*-
from conv_gen import ConvolutionalCode
from conv_gen import poly
@ -49,6 +49,15 @@ conv_codes = [
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 = "rach_ext",
description = ["Extended RACH (11 bit) convolutional code"]
),
# SCH definition
ConvolutionalCode(
35,