mirror of https://gerrit.osmocom.org/libosmocore
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:
parent
9dd3bf0cb4
commit
32e5641dbb
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -97,6 +97,7 @@ gsm0502_calc_paging_group;
|
|||
|
||||
gsm0503_xcch;
|
||||
gsm0503_rach;
|
||||
gsm0503_rach_ext;
|
||||
gsm0503_sch;
|
||||
gsm0503_cs2;
|
||||
gsm0503_cs3;
|
||||
|
|
|
@ -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
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue