Get rid of class GprsCodingScheme

We have same kind of object splitted into two layers, in coding_scheme
and gprs_coding_scheme. Let's merge them together and get rid of the
class, which is not really useful because it's only a set of functions
operating on one enum value.

This change also fixes gcc 10.1.0 error about memseting a complex type
in rlc.h init().

Change-Id: Ie9ce2144ba9e8dbba9704d4e0000a2929e3e41df
This commit is contained in:
Pau Espin 2020-05-18 11:35:35 +02:00 committed by pespin
parent c10cb81593
commit 2ae8337669
26 changed files with 541 additions and 686 deletions

View File

@ -68,7 +68,6 @@ libgprs_la_SOURCES = \
osmobts_sock.cpp \ osmobts_sock.cpp \
gprs_codel.c \ gprs_codel.c \
coding_scheme.c \ coding_scheme.c \
gprs_coding_scheme.cpp \
egprs_rlc_compression.cpp \ egprs_rlc_compression.cpp \
gprs_rlcmac_sched.cpp gprs_rlcmac_sched.cpp
@ -104,7 +103,6 @@ noinst_HEADERS = \
pcu_utils.h \ pcu_utils.h \
cxx_linuxlist.h \ cxx_linuxlist.h \
gprs_codel.h \ gprs_codel.h \
gprs_coding_scheme.h \
coding_scheme.h \ coding_scheme.h \
egprs_rlc_compression.h \ egprs_rlc_compression.h \
wireshark_compat.h wireshark_compat.h

View File

@ -37,7 +37,7 @@ extern "C" {
#include "sba.h" #include "sba.h"
#include "tbf.h" #include "tbf.h"
#include "gprs_ms_storage.h" #include "gprs_ms_storage.h"
#include "gprs_coding_scheme.h" #include "coding_scheme.h"
#include <cxx_linuxlist.h> #include <cxx_linuxlist.h>
#endif #endif

View File

@ -42,6 +42,56 @@ const struct value_string mcs_names[] = {
{ 0, NULL } { 0, NULL }
}; };
enum Family {
FAMILY_INVALID,
FAMILY_A,
FAMILY_B,
FAMILY_C,
};
static struct {
struct {
uint8_t bytes;
uint8_t ext_bits;
uint8_t data_header_bits;
} uplink, downlink;
uint8_t data_bytes;
uint8_t optional_padding_bits;
enum HeaderType data_hdr;
enum Family family;
} mcs_info[NUM_SCHEMES] = {
{{0, 0}, {0, 0}, 0, 0,
HEADER_INVALID, FAMILY_INVALID},
{{23, 0}, {23, 0}, 20, 0,
HEADER_GPRS_DATA, FAMILY_INVALID},
{{33, 7}, {33, 7}, 30, 0,
HEADER_GPRS_DATA, FAMILY_INVALID},
{{39, 3}, {39, 3}, 36, 0,
HEADER_GPRS_DATA, FAMILY_INVALID},
{{53, 7}, {53, 7}, 50, 0,
HEADER_GPRS_DATA, FAMILY_INVALID},
{{26, 1}, {26, 1}, 22, 0,
HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},
{{32, 1}, {32, 1}, 28, 0,
HEADER_EGPRS_DATA_TYPE_3, FAMILY_B},
{{41, 1}, {41, 1}, 37, 48,
HEADER_EGPRS_DATA_TYPE_3, FAMILY_A},
{{48, 1}, {48, 1}, 44, 0,
HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},
{{60, 7}, {59, 6}, 56, 0,
HEADER_EGPRS_DATA_TYPE_2, FAMILY_B},
{{78, 7}, {77, 6}, 74, 48,
HEADER_EGPRS_DATA_TYPE_2, FAMILY_A},
{{118, 2}, {117, 4}, 56, 0,
HEADER_EGPRS_DATA_TYPE_1, FAMILY_B},
{{142, 2}, {141, 4}, 68, 0,
HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},
{{154, 2}, {153, 4}, 74, 0,
HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},
};
const char *mcs_name(enum CodingScheme val) { const char *mcs_name(enum CodingScheme val) {
return get_value_string(mcs_names, val); return get_value_string(mcs_names, val);
} }
@ -77,6 +127,194 @@ uint8_t mcs_chan_code(enum CodingScheme cs)
return 0; return 0;
} }
enum CodingScheme mcs_get_by_size_ul(unsigned size)
{
switch (size) {
case 23: return CS1;
case 27: return MCS1;
case 33: return MCS2;
case 34: return CS2;
case 40: return CS3;
case 42: return MCS3;
case 49: return MCS4;
case 54: return CS4;
case 61: return MCS5;
case 79: return MCS6;
case 119: return MCS7;
case 143: return MCS8;
case 155: return MCS9;
default: return UNKNOWN;
}
}
enum CodingScheme mcs_get_gprs_by_num(unsigned num)
{
if (num < 1 || num > 4)
return UNKNOWN;
return CS1 + (num - 1);
}
enum CodingScheme mcs_get_egprs_by_num(unsigned num)
{
if (num < 1 || num > 9)
return UNKNOWN;
return MCS1 + (num - 1);
}
bool mcs_is_valid(enum CodingScheme cs)
{
return UNKNOWN <= cs && cs <= MCS9;
}
bool mcs_is_compat_kind(enum CodingScheme cs, enum mcs_kind mode)
{
switch (mode) {
case GPRS: return mcs_is_gprs(cs);
case EGPRS_GMSK: return mcs_is_edge_gmsk(cs);
case EGPRS: return mcs_is_edge(cs);
}
return false;
}
bool mcs_is_compat(enum CodingScheme cs, enum CodingScheme o)
{
return (mcs_is_gprs(cs) && mcs_is_gprs(o)) || (mcs_is_edge(cs) && mcs_is_edge(o));
}
uint8_t mcs_size_ul(enum CodingScheme cs)
{
return mcs_info[cs].uplink.bytes + (mcs_spare_bits_ul(cs) ? 1 : 0);
}
uint8_t mcs_size_dl(enum CodingScheme cs)
{
return mcs_info[cs].downlink.bytes + (mcs_spare_bits_dl(cs) ? 1 : 0);
}
uint8_t mcs_used_size_ul(enum CodingScheme cs)
{
if (mcs_info[cs].data_hdr == HEADER_GPRS_DATA)
return mcs_info[cs].uplink.bytes;
else
return mcs_size_ul(cs);
}
uint8_t mcs_used_size_dl(enum CodingScheme cs)
{
if (mcs_info[cs].data_hdr == HEADER_GPRS_DATA)
return mcs_info[cs].downlink.bytes;
else
return mcs_size_dl(cs);
}
uint8_t mcs_max_bytes_ul(enum CodingScheme cs)
{
return mcs_info[cs].uplink.bytes;
}
uint8_t mcs_max_bytes_dl(enum CodingScheme cs)
{
return mcs_info[cs].downlink.bytes;
}
uint8_t mcs_spare_bits_ul(enum CodingScheme cs)
{
return mcs_info[cs].uplink.ext_bits;
}
uint8_t mcs_spare_bits_dl(enum CodingScheme cs)
{
return mcs_info[cs].downlink.ext_bits;
}
uint8_t mcs_max_data_block_bytes(enum CodingScheme cs)
{
return mcs_info[cs].data_bytes;
}
uint8_t mcs_opt_padding_bits(enum CodingScheme cs)
{
return mcs_info[cs].optional_padding_bits;
}
void mcs_inc_kind(enum CodingScheme *cs, enum mcs_kind mode)
{
if (!mcs_is_compat_kind(*cs, mode))
/* This should not happen. TODO: Use assert? */
return;
enum CodingScheme new_cs = *cs + 1;
if (!mcs_is_compat_kind(new_cs, mode))
/* Clipping, do not change the value */
return;
*cs = new_cs;
}
void mcs_dec_kind(enum CodingScheme *cs, enum mcs_kind mode)
{
if (!mcs_is_compat_kind(*cs, mode))
/* This should not happen. TODO: Use assert? */
return;
enum CodingScheme new_cs = *cs - 1;
if (!mcs_is_compat_kind(new_cs, mode))
/* Clipping, do not change the value */
return;
*cs = new_cs;
}
void mcs_inc(enum CodingScheme *cs)
{
if (mcs_is_gprs(*cs) && *cs == CS4)
return;
if (mcs_is_edge(*cs) && *cs == MCS9)
return;
if (!mcs_is_valid(*cs))
return;
*cs = *cs + 1;
}
void mcs_dec(enum CodingScheme *cs)
{
if (mcs_is_gprs(*cs) && *cs == CS1)
return;
if (mcs_is_edge(*cs) && *cs == MCS1)
return;
if (!mcs_is_valid(*cs))
return;
*cs = *cs - 1;
}
bool mcs_is_family_compat(enum CodingScheme cs, enum CodingScheme o)
{
if (cs == o)
return true;
if (mcs_info[cs].family == FAMILY_INVALID)
return false;
return mcs_info[cs].family == mcs_info[o].family;
}
void mcs_dec_to_single_block(enum CodingScheme *cs, bool *need_stuffing)
{
switch (*cs) {
case MCS7: *need_stuffing = false; *cs = MCS5; break;
case MCS8: *need_stuffing = true; *cs = MCS6; break;
case MCS9: *need_stuffing = false; *cs = MCS6; break;
default: *need_stuffing = false; break;
}
}
static struct { static struct {
struct { struct {
uint8_t data_header_bits; uint8_t data_header_bits;
@ -93,6 +331,11 @@ static struct {
{ { 3 * 8 + 7 }, { 3 * 8 + 7 }, 2, 1, "EGPRS_DATA_TYPE3" }, { { 3 * 8 + 7 }, { 3 * 8 + 7 }, 2, 1, "EGPRS_DATA_TYPE3" },
}; };
enum HeaderType mcs_header_type(enum CodingScheme mcs)
{
return mcs_info[mcs].data_hdr;
}
uint8_t num_data_blocks(enum HeaderType ht) uint8_t num_data_blocks(enum HeaderType ht)
{ {
OSMO_ASSERT(ht < NUM_HEADER_TYPES); OSMO_ASSERT(ht < NUM_HEADER_TYPES);

View File

@ -21,6 +21,8 @@
#include <osmocom/core/utils.h> #include <osmocom/core/utils.h>
#include <stdbool.h>
enum CodingScheme { enum CodingScheme {
UNKNOWN, UNKNOWN,
/* GPRS Coding Schemes: */ /* GPRS Coding Schemes: */
@ -30,6 +32,15 @@ enum CodingScheme {
NUM_SCHEMES NUM_SCHEMES
}; };
enum mcs_kind {
GPRS,
EGPRS_GMSK,
EGPRS,
};
#define EGPRS_ARQ1 0x0
#define EGPRS_ARQ2 0x1
extern const struct value_string mcs_names[]; extern const struct value_string mcs_names[];
const char *mcs_name(enum CodingScheme val); const char *mcs_name(enum CodingScheme val);
enum CodingScheme get_retx_mcs(enum CodingScheme initial_mcs, enum CodingScheme commanded_mcs, bool resegment_bit); enum CodingScheme get_retx_mcs(enum CodingScheme initial_mcs, enum CodingScheme commanded_mcs, bool resegment_bit);
@ -40,6 +51,32 @@ bool mcs_is_edge_gmsk(enum CodingScheme cs);
uint8_t mcs_chan_code(enum CodingScheme cs); uint8_t mcs_chan_code(enum CodingScheme cs);
enum CodingScheme mcs_get_by_size_ul(unsigned size);
enum CodingScheme mcs_get_gprs_by_num(unsigned num);
enum CodingScheme mcs_get_egprs_by_num(unsigned num);
bool mcs_is_valid(enum CodingScheme cs);
bool mcs_is_compat(enum CodingScheme cs, enum CodingScheme o);
bool mcs_is_compat_kind(enum CodingScheme cs, enum mcs_kind mode);
uint8_t mcs_size_ul(enum CodingScheme cs);
uint8_t mcs_size_dl(enum CodingScheme cs);
uint8_t mcs_used_size_ul(enum CodingScheme cs);
uint8_t mcs_used_size_dl(enum CodingScheme cs);
uint8_t mcs_max_bytes_ul(enum CodingScheme cs);
uint8_t mcs_max_bytes_dl(enum CodingScheme cs);
uint8_t mcs_spare_bits_ul(enum CodingScheme cs);
uint8_t mcs_spare_bits_dl(enum CodingScheme cs);
uint8_t mcs_max_data_block_bytes(enum CodingScheme cs);
uint8_t mcs_opt_padding_bits(enum CodingScheme cs);
void mcs_inc_kind(enum CodingScheme *cs, enum mcs_kind mode);
void mcs_dec_kind(enum CodingScheme *cs, enum mcs_kind mode);
void mcs_inc(enum CodingScheme *cs);
void mcs_dec(enum CodingScheme *cs);
bool mcs_is_family_compat(enum CodingScheme cs, enum CodingScheme o);
void mcs_dec_to_single_block(enum CodingScheme *cs, bool *need_stuffing);
enum HeaderType { enum HeaderType {
HEADER_INVALID, HEADER_INVALID,
HEADER_GPRS_CONTROL, HEADER_GPRS_CONTROL,
@ -50,17 +87,11 @@ enum HeaderType {
NUM_HEADER_TYPES NUM_HEADER_TYPES
}; };
enum HeaderType headerTypeData(enum CodingScheme mcs); enum HeaderType mcs_header_type(enum CodingScheme mcs);
uint8_t num_data_blocks(enum HeaderType ht); uint8_t num_data_blocks(enum HeaderType ht);
uint8_t num_data_header_bits_UL(enum HeaderType ht); uint8_t num_data_header_bits_UL(enum HeaderType ht);
uint8_t num_data_header_bits_DL(enum HeaderType ht); uint8_t num_data_header_bits_DL(enum HeaderType ht);
uint8_t num_data_block_header_bits(enum HeaderType ht); uint8_t num_data_block_header_bits(enum HeaderType ht);
enum mcs_kind {
GPRS,
EGPRS_GMSK,
EGPRS,
};
const char *mode_name(enum mcs_kind val); const char *mode_name(enum mcs_kind val);

View File

@ -189,7 +189,7 @@ static int parse_extensions_gprs(const uint8_t *data, unsigned int data_len,
} }
int Decoding::rlc_data_from_ul_data( int Decoding::rlc_data_from_ul_data(
const struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, const struct gprs_rlc_data_block_info *rdbi, enum CodingScheme cs,
const uint8_t *data, RlcData *chunks, unsigned int chunks_size, const uint8_t *data, RlcData *chunks, unsigned int chunks_size,
uint32_t *tlli) uint32_t *tlli)
{ {
@ -351,10 +351,10 @@ void Decoding::extract_rbb(const struct bitvec *rbb, char *show_rbb)
} }
int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
const uint8_t *data, GprsCodingScheme cs) const uint8_t *data, enum CodingScheme cs)
{ {
unsigned int cur_bit = 0; unsigned int cur_bit = 0;
switch(cs.headerTypeData()) { switch(mcs_header_type(cs)) {
case HEADER_GPRS_DATA : case HEADER_GPRS_DATA :
cur_bit = rlc_parse_ul_data_header_gprs(rlc, data, cs); cur_bit = rlc_parse_ul_data_header_gprs(rlc, data, cs);
break; break;
@ -380,7 +380,7 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
int Decoding::rlc_parse_ul_data_header_egprs_type_3( int Decoding::rlc_parse_ul_data_header_egprs_type_3(
struct gprs_rlc_data_info *rlc, struct gprs_rlc_data_info *rlc,
const uint8_t *data, const uint8_t *data,
const GprsCodingScheme &cs) const enum CodingScheme &cs)
{ {
int punct, punct2, with_padding, cps; int punct, punct2, with_padding, cps;
unsigned int e_ti_header, offs, cur_bit = 0; unsigned int e_ti_header, offs, cur_bit = 0;
@ -414,7 +414,7 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_3(
rlc->block_info[0].ti = !!(e_ti_header & 0x02); rlc->block_info[0].ti = !!(e_ti_header & 0x02);
cur_bit += 2; cur_bit += 2;
/* skip data area */ /* skip data area */
cur_bit += cs.maxDataBlockBytes() * 8; cur_bit += mcs_max_data_block_bytes(cs) * 8;
return cur_bit; return cur_bit;
} }
@ -422,7 +422,7 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_3(
int Decoding::rlc_parse_ul_data_header_egprs_type_2( int Decoding::rlc_parse_ul_data_header_egprs_type_2(
struct gprs_rlc_data_info *rlc, struct gprs_rlc_data_info *rlc,
const uint8_t *data, const uint8_t *data,
const GprsCodingScheme &cs) const enum CodingScheme &cs)
{ {
const struct gprs_rlc_ul_header_egprs_2 *egprs2; const struct gprs_rlc_ul_header_egprs_2 *egprs2;
unsigned int e_ti_header, offs, cur_bit = 0; unsigned int e_ti_header, offs, cur_bit = 0;
@ -458,14 +458,14 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_2(
cur_bit += 2; cur_bit += 2;
/* skip data area */ /* skip data area */
cur_bit += cs.maxDataBlockBytes() * 8; cur_bit += mcs_max_data_block_bytes(cs) * 8;
return cur_bit; return cur_bit;
} }
int Decoding::rlc_parse_ul_data_header_egprs_type_1( int Decoding::rlc_parse_ul_data_header_egprs_type_1(
struct gprs_rlc_data_info *rlc, struct gprs_rlc_data_info *rlc,
const uint8_t *data, const GprsCodingScheme &cs) const uint8_t *data, const enum CodingScheme &cs)
{ {
struct gprs_rlc_ul_header_egprs_1 *egprs1; struct gprs_rlc_ul_header_egprs_1 *egprs1;
unsigned int e_ti_header, cur_bit = 0, offs; unsigned int e_ti_header, cur_bit = 0, offs;
@ -517,13 +517,13 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_1(
rlc->block_info[1].ti = !!(e_ti_header & 0x02); rlc->block_info[1].ti = !!(e_ti_header & 0x02);
cur_bit += 2; cur_bit += 2;
/* skip data area */ /* skip data area */
cur_bit += cs.maxDataBlockBytes() * 8; cur_bit += mcs_max_data_block_bytes(cs) * 8;
return cur_bit; return cur_bit;
} }
int Decoding::rlc_parse_ul_data_header_gprs(struct gprs_rlc_data_info *rlc, int Decoding::rlc_parse_ul_data_header_gprs(struct gprs_rlc_data_info *rlc,
const uint8_t *data, const GprsCodingScheme &cs) const uint8_t *data, const enum CodingScheme &cs)
{ {
const struct rlc_ul_header *gprs; const struct rlc_ul_header *gprs;
unsigned int cur_bit = 0; unsigned int cur_bit = 0;
@ -547,7 +547,7 @@ int Decoding::rlc_parse_ul_data_header_gprs(struct gprs_rlc_data_info *rlc,
rlc->block_info[0].spb = 0; rlc->block_info[0].spb = 0;
cur_bit += rlc->data_offs_bits[0]; cur_bit += rlc->data_offs_bits[0];
/* skip data area */ /* skip data area */
cur_bit += cs.maxDataBlockBytes() * 8; cur_bit += mcs_max_data_block_bytes(cs) * 8;
return cur_bit; return cur_bit;
} }

View File

@ -40,7 +40,7 @@ public:
static int rlc_data_from_ul_data( static int rlc_data_from_ul_data(
const struct gprs_rlc_data_block_info *rdbi, const struct gprs_rlc_data_block_info *rdbi,
GprsCodingScheme cs, const uint8_t *data, RlcData *chunks, enum CodingScheme cs, const uint8_t *data, RlcData *chunks,
unsigned int chunks_size, uint32_t *tlli); unsigned int chunks_size, uint32_t *tlli);
static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap); static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap);
static uint8_t get_egprs_ms_class_by_capability(MS_Radio_Access_capability_t *cap); static uint8_t get_egprs_ms_class_by_capability(MS_Radio_Access_capability_t *cap);
@ -50,21 +50,21 @@ public:
static int rlc_parse_ul_data_header_egprs_type_3( static int rlc_parse_ul_data_header_egprs_type_3(
struct gprs_rlc_data_info *rlc, struct gprs_rlc_data_info *rlc,
const uint8_t *data, const uint8_t *data,
const GprsCodingScheme &cs); const enum CodingScheme &cs);
static int rlc_parse_ul_data_header_egprs_type_2( static int rlc_parse_ul_data_header_egprs_type_2(
struct gprs_rlc_data_info *rlc, struct gprs_rlc_data_info *rlc,
const uint8_t *data, const uint8_t *data,
const GprsCodingScheme &cs); const enum CodingScheme &cs);
static int rlc_parse_ul_data_header_egprs_type_1( static int rlc_parse_ul_data_header_egprs_type_1(
struct gprs_rlc_data_info *rlc, struct gprs_rlc_data_info *rlc,
const uint8_t *data, const uint8_t *data,
const GprsCodingScheme &cs); const enum CodingScheme &cs);
static int rlc_parse_ul_data_header_gprs( static int rlc_parse_ul_data_header_gprs(
struct gprs_rlc_data_info *rlc, struct gprs_rlc_data_info *rlc,
const uint8_t *data, const uint8_t *data,
const GprsCodingScheme &cs); const enum CodingScheme &cs);
static int rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc, static int rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
const uint8_t *data, GprsCodingScheme cs); const uint8_t *data, enum CodingScheme cs);
static unsigned int rlc_copy_to_aligned_buffer( static unsigned int rlc_copy_to_aligned_buffer(
const struct gprs_rlc_data_info *rlc, const struct gprs_rlc_data_info *rlc,
unsigned int data_block_idx, unsigned int data_block_idx,

View File

@ -1107,11 +1107,11 @@ int Encoding::rlc_write_dl_data_header(const struct gprs_rlc_data_info *rlc,
struct gprs_rlc_dl_header_egprs_3 *egprs3; struct gprs_rlc_dl_header_egprs_3 *egprs3;
struct rlc_dl_header *gprs; struct rlc_dl_header *gprs;
unsigned int e_fbi_header; unsigned int e_fbi_header;
GprsCodingScheme cs = rlc->cs; enum CodingScheme cs = rlc->cs;
unsigned int offs; unsigned int offs;
unsigned int bsn_delta; unsigned int bsn_delta;
switch(cs.headerTypeData()) { switch(mcs_header_type(cs)) {
case HEADER_GPRS_DATA: case HEADER_GPRS_DATA:
gprs = static_cast<struct rlc_dl_header *> gprs = static_cast<struct rlc_dl_header *>
((void *)data); ((void *)data);
@ -1595,7 +1595,7 @@ static Encoding::AppendResult rlc_data_to_dl_append_egprs(
* \return the state of the rlc/mac like if there is more space for another chunk * \return the state of the rlc/mac like if there is more space for another chunk
*/ */
Encoding::AppendResult Encoding::rlc_data_to_dl_append( Encoding::AppendResult Encoding::rlc_data_to_dl_append(
struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, struct gprs_rlc_data_block_info *rdbi, enum CodingScheme cs,
gprs_llc *llc, int *offset, int *num_chunks, gprs_llc *llc, int *offset, int *num_chunks,
uint8_t *data_block, bool is_final, int *count_payload) uint8_t *data_block, bool is_final, int *count_payload)
{ {

View File

@ -21,9 +21,10 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <gprs_coding_scheme.h>
extern "C" { extern "C" {
#include <osmocom/gsm/l1sap.h> #include <osmocom/gsm/l1sap.h>
#include "coding_scheme.h"
#include "gsm_rlcmac.h" #include "gsm_rlcmac.h"
} }
@ -99,7 +100,7 @@ public:
}; };
static AppendResult rlc_data_to_dl_append( static AppendResult rlc_data_to_dl_append(
struct gprs_rlc_data_block_info *rdbi, GprsCodingScheme cs, struct gprs_rlc_data_block_info *rdbi, enum CodingScheme cs,
gprs_llc *llc, int *offset, int *num_chunks, gprs_llc *llc, int *offset, int *num_chunks,
uint8_t *data, bool is_final, int *count_payload); uint8_t *data, bool is_final, int *count_payload);
}; };

View File

@ -24,7 +24,7 @@
#include <gprs_debug.h> #include <gprs_debug.h>
#include <bts.h> #include <bts.h>
#include <tbf.h> #include <tbf.h>
#include <gprs_coding_scheme.h> #include <coding_scheme.h>
#include <pdch.h> #include <pdch.h>
#include <decoding.h> #include <decoding.h>
@ -639,9 +639,9 @@ static unsigned count_pdch(const struct gprs_rlcmac_bts *bts)
return num_pdch; return num_pdch;
} }
static uint32_t gprs_bssgp_max_leak_rate(GprsCodingScheme cs, int num_pdch) static uint32_t gprs_bssgp_max_leak_rate(enum CodingScheme cs, int num_pdch)
{ {
int bytes_per_rlc_block = cs.maxDataBlockBytes() * num_data_blocks(cs.headerTypeData()); int bytes_per_rlc_block = mcs_max_data_block_bytes(cs) * num_data_blocks(mcs_header_type(cs));
/* n byte payload per 20ms */ /* n byte payload per 20ms */
return bytes_per_rlc_block * (1000 / 20) * num_pdch; return bytes_per_rlc_block * (1000 / 20) * num_pdch;
@ -717,7 +717,7 @@ static int get_and_reset_measured_leak_rate(int *usage_by_1000, unsigned num_pdc
return rate; return rate;
} }
static GprsCodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts) static enum CodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts)
{ {
int num; int num;
@ -733,7 +733,7 @@ static GprsCodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts)
num = 9; num = 9;
} }
return GprsCodingScheme::getEgprsByNum(num); return mcs_get_egprs_by_num(num);
} }
if (!bts->cs_adj_enabled) { if (!bts->cs_adj_enabled) {
@ -753,7 +753,7 @@ static GprsCodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts)
num = 4; num = 4;
} }
return GprsCodingScheme::getGprsByNum(num); return mcs_get_gprs_by_num(num);
} }
static int gprs_bssgp_tx_fc_bvc(void) static int gprs_bssgp_tx_fc_bvc(void)
@ -765,7 +765,7 @@ static int gprs_bssgp_tx_fc_bvc(void)
uint32_t ms_leak_rate; /* oct/s */ uint32_t ms_leak_rate; /* oct/s */
uint32_t avg_delay_ms; uint32_t avg_delay_ms;
int num_pdch = -1; int num_pdch = -1;
GprsCodingScheme max_cs_dl; enum CodingScheme max_cs_dl;
if (!the_pcu.bctx) { if (!the_pcu.bctx) {
LOGP(DBSSGP, LOGL_ERROR, "No bctx\n"); LOGP(DBSSGP, LOGL_ERROR, "No bctx\n");

View File

@ -1,231 +0,0 @@
/* gprs_coding_scheme.cpp
*
* Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
* Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "gprs_coding_scheme.h"
enum Family {
FAMILY_INVALID,
FAMILY_A,
FAMILY_B,
FAMILY_C,
};
static struct {
struct {
uint8_t bytes;
uint8_t ext_bits;
uint8_t data_header_bits;
} uplink, downlink;
uint8_t data_bytes;
uint8_t optional_padding_bits;
enum HeaderType data_hdr;
enum Family family;
} mcs_info[NUM_SCHEMES] = {
{{0, 0}, {0, 0}, 0, 0,
HEADER_INVALID, FAMILY_INVALID},
{{23, 0}, {23, 0}, 20, 0,
HEADER_GPRS_DATA, FAMILY_INVALID},
{{33, 7}, {33, 7}, 30, 0,
HEADER_GPRS_DATA, FAMILY_INVALID},
{{39, 3}, {39, 3}, 36, 0,
HEADER_GPRS_DATA, FAMILY_INVALID},
{{53, 7}, {53, 7}, 50, 0,
HEADER_GPRS_DATA, FAMILY_INVALID},
{{26, 1}, {26, 1}, 22, 0,
HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},
{{32, 1}, {32, 1}, 28, 0,
HEADER_EGPRS_DATA_TYPE_3, FAMILY_B},
{{41, 1}, {41, 1}, 37, 48,
HEADER_EGPRS_DATA_TYPE_3, FAMILY_A},
{{48, 1}, {48, 1}, 44, 0,
HEADER_EGPRS_DATA_TYPE_3, FAMILY_C},
{{60, 7}, {59, 6}, 56, 0,
HEADER_EGPRS_DATA_TYPE_2, FAMILY_B},
{{78, 7}, {77, 6}, 74, 48,
HEADER_EGPRS_DATA_TYPE_2, FAMILY_A},
{{118, 2}, {117, 4}, 56, 0,
HEADER_EGPRS_DATA_TYPE_1, FAMILY_B},
{{142, 2}, {141, 4}, 68, 0,
HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},
{{154, 2}, {153, 4}, 74, 0,
HEADER_EGPRS_DATA_TYPE_1, FAMILY_A},
};
GprsCodingScheme GprsCodingScheme::getBySizeUL(unsigned size)
{
switch (size) {
case 23: return GprsCodingScheme(CS1);
case 27: return GprsCodingScheme(MCS1);
case 33: return GprsCodingScheme(MCS2);
case 34: return GprsCodingScheme(CS2);
case 40: return GprsCodingScheme(CS3);
case 42: return GprsCodingScheme(MCS3);
case 49: return GprsCodingScheme(MCS4);
case 54: return GprsCodingScheme(CS4);
case 61: return GprsCodingScheme(MCS5);
case 79: return GprsCodingScheme(MCS6);
case 119: return GprsCodingScheme(MCS7);
case 143: return GprsCodingScheme(MCS8);
case 155: return GprsCodingScheme(MCS9);
}
return GprsCodingScheme(UNKNOWN);
}
uint8_t GprsCodingScheme::sizeUL() const
{
return mcs_info[m_scheme].uplink.bytes + (spareBitsUL() ? 1 : 0);
}
uint8_t GprsCodingScheme::usedSizeUL() const
{
if (mcs_info[m_scheme].data_hdr == HEADER_GPRS_DATA)
return mcs_info[m_scheme].uplink.bytes;
else
return sizeUL();
}
uint8_t GprsCodingScheme::maxBytesUL() const
{
return mcs_info[m_scheme].uplink.bytes;
}
uint8_t GprsCodingScheme::spareBitsUL() const
{
return mcs_info[m_scheme].uplink.ext_bits;
}
uint8_t GprsCodingScheme::sizeDL() const
{
return mcs_info[m_scheme].downlink.bytes + (spareBitsDL() ? 1 : 0);
}
uint8_t GprsCodingScheme::usedSizeDL() const
{
if (mcs_info[m_scheme].data_hdr == HEADER_GPRS_DATA)
return mcs_info[m_scheme].downlink.bytes;
else
return sizeDL();
}
uint8_t GprsCodingScheme::maxBytesDL() const
{
return mcs_info[m_scheme].downlink.bytes;
}
uint8_t GprsCodingScheme::spareBitsDL() const
{
return mcs_info[m_scheme].downlink.ext_bits;
}
uint8_t GprsCodingScheme::maxDataBlockBytes() const
{
return mcs_info[m_scheme].data_bytes;
}
uint8_t GprsCodingScheme::optionalPaddingBits() const
{
return mcs_info[m_scheme].optional_padding_bits;
}
enum HeaderType GprsCodingScheme::headerTypeData() const
{
return mcs_info[m_scheme].data_hdr;
}
void GprsCodingScheme::inc(enum mcs_kind mode)
{
if (!isCompatible(mode))
/* This should not happen. TODO: Use assert? */
return;
CodingScheme new_cs(CodingScheme(m_scheme + 1));
if (!GprsCodingScheme(new_cs).isCompatible(mode))
/* Clipping, do not change the value */
return;
m_scheme = new_cs;
}
void GprsCodingScheme::dec(enum mcs_kind mode)
{
if (!isCompatible(mode))
/* This should not happen. TODO: Use assert? */
return;
CodingScheme new_cs(CodingScheme(m_scheme - 1));
if (!GprsCodingScheme(new_cs).isCompatible(mode))
/* Clipping, do not change the value */
return;
m_scheme = new_cs;
}
void GprsCodingScheme::inc()
{
if (mcs_is_gprs(m_scheme) && m_scheme == CS4)
return;
if (mcs_is_edge(m_scheme) && m_scheme == MCS9)
return;
if (!isValid())
return;
m_scheme = CodingScheme(m_scheme + 1);
}
void GprsCodingScheme::dec()
{
if (mcs_is_gprs(m_scheme) && m_scheme == CS1)
return;
if (mcs_is_edge(m_scheme) && m_scheme == MCS1)
return;
if (!isValid())
return;
m_scheme = CodingScheme(m_scheme - 1);
}
bool GprsCodingScheme::isFamilyCompatible(GprsCodingScheme o) const
{
if (*this == o)
return true;
if (mcs_info[m_scheme].family == FAMILY_INVALID)
return false;
return mcs_info[m_scheme].family == mcs_info[o.m_scheme].family;
}
void GprsCodingScheme::decToSingleBlock(bool *needStuffing)
{
switch (m_scheme) {
case MCS7: *needStuffing = false; m_scheme = MCS5; break;
case MCS8: *needStuffing = true; m_scheme = MCS6; break;
case MCS9: *needStuffing = false; m_scheme = MCS6; break;
default: *needStuffing = false; break;
}
}

View File

@ -1,163 +0,0 @@
/* gprs_coding_scheme.h
*
* Copyright (C) 2015 by Sysmocom s.f.m.c. GmbH
* Author: Jacob Erlbeck <jerlbeck@sysmocom.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#pragma once
#include <stdint.h>
#include <stddef.h>
extern "C" {
#include <osmocom/core/utils.h>
#include "coding_scheme.h"
}
class GprsCodingScheme {
public:
#define EGPRS_ARQ1 0x0
#define EGPRS_ARQ2 0x1
GprsCodingScheme(CodingScheme s = UNKNOWN);
operator bool() const {return m_scheme != UNKNOWN;}
operator CodingScheme() const {return m_scheme;}
uint8_t to_num() const;
GprsCodingScheme& operator =(CodingScheme s);
bool operator == (CodingScheme s) const;
GprsCodingScheme& operator =(GprsCodingScheme o);
bool isValid() const {return UNKNOWN <= m_scheme && m_scheme <= MCS9;}
bool isCompatible(enum mcs_kind mode) const;
bool isCompatible(GprsCodingScheme o) const;
bool isFamilyCompatible(GprsCodingScheme o) const;
void inc(enum mcs_kind mode);
void dec(enum mcs_kind mode);
void inc();
void dec();
void decToSingleBlock(bool *needStuffing);
uint8_t sizeUL() const;
uint8_t sizeDL() const;
uint8_t usedSizeUL() const;
uint8_t usedSizeDL() const;
uint8_t maxBytesUL() const;
uint8_t maxBytesDL() const;
uint8_t spareBitsUL() const;
uint8_t spareBitsDL() const;
uint8_t maxDataBlockBytes() const;
uint8_t optionalPaddingBits() const;
enum HeaderType headerTypeData() const;
static GprsCodingScheme getBySizeUL(unsigned size);
static GprsCodingScheme getGprsByNum(unsigned num);
static GprsCodingScheme getEgprsByNum(unsigned num);
private:
GprsCodingScheme(int s); /* fail on use */
GprsCodingScheme& operator =(int s); /* fail on use */
enum CodingScheme m_scheme;
};
// FIXME: remove once < comparison operator below is no longer necessary
inline uint8_t GprsCodingScheme::to_num() const
{
if (mcs_is_gprs(m_scheme))
return (m_scheme - CS1) + 1;
if (mcs_is_edge(m_scheme))
return (m_scheme - MCS1) + 1;
return 0;
}
inline bool GprsCodingScheme::isCompatible(enum mcs_kind mode) const
{
switch (mode) {
case GPRS: return mcs_is_gprs(m_scheme);
case EGPRS_GMSK: return mcs_is_edge_gmsk(m_scheme);
case EGPRS: return mcs_is_edge(m_scheme);
}
return false;
}
inline bool GprsCodingScheme::isCompatible(GprsCodingScheme o) const
{
return (mcs_is_gprs(m_scheme) && mcs_is_gprs(o)) || (mcs_is_edge(m_scheme) && mcs_is_edge(o));
}
inline GprsCodingScheme::GprsCodingScheme(CodingScheme s)
: m_scheme(s)
{
if (!isValid())
m_scheme = UNKNOWN;
}
inline GprsCodingScheme& GprsCodingScheme::operator =(CodingScheme s)
{
m_scheme = s;
if (!isValid())
m_scheme = UNKNOWN;
return *this;
}
inline GprsCodingScheme& GprsCodingScheme::operator =(GprsCodingScheme o)
{
m_scheme = o.m_scheme;
return *this;
}
inline GprsCodingScheme GprsCodingScheme::getGprsByNum(unsigned num)
{
if (num < 1 || num > 4)
return GprsCodingScheme();
return GprsCodingScheme(CodingScheme(CS1 + (num - 1)));
}
inline GprsCodingScheme GprsCodingScheme::getEgprsByNum(unsigned num)
{
if (num < 1 || num > 9)
return GprsCodingScheme();
return GprsCodingScheme(CodingScheme(MCS1 + (num - 1)));
}
/* The coding schemes form a partial ordering */
inline bool GprsCodingScheme::operator == (CodingScheme scheme) const
{
return this->m_scheme == scheme;
}
inline bool operator !=(GprsCodingScheme a, GprsCodingScheme b)
{
return !(a == b);
}
inline bool operator <(GprsCodingScheme a, GprsCodingScheme b)
{
return a.isCompatible(b) && a.to_num() < b.to_num();
}

View File

@ -20,7 +20,6 @@
#include "gprs_ms.h" #include "gprs_ms.h"
#include <gprs_coding_scheme.h>
#include "bts.h" #include "bts.h"
#include "tbf.h" #include "tbf.h"
#include "tbf_ul.h" #include "tbf_ul.h"
@ -103,6 +102,8 @@ GprsMs::GprsMs(BTS *bts, uint32_t tlli) :
m_ta(GSM48_TA_INVALID), m_ta(GSM48_TA_INVALID),
m_ms_class(0), m_ms_class(0),
m_egprs_ms_class(0), m_egprs_ms_class(0),
m_current_cs_ul(UNKNOWN),
m_current_cs_dl(UNKNOWN),
m_is_idle(true), m_is_idle(true),
m_ref(0), m_ref(0),
m_list(this), m_list(this),
@ -226,15 +227,15 @@ void GprsMs::set_mode(enum mcs_kind mode)
switch (m_mode) { switch (m_mode) {
case GPRS: case GPRS:
if (!mcs_is_gprs(m_current_cs_ul)) { if (!mcs_is_gprs(m_current_cs_ul)) {
m_current_cs_ul = GprsCodingScheme::getGprsByNum( m_current_cs_ul = mcs_get_gprs_by_num(
m_bts->bts_data()->initial_cs_ul); m_bts->bts_data()->initial_cs_ul);
if (!m_current_cs_ul.isValid()) if (!mcs_is_valid(m_current_cs_ul))
m_current_cs_ul = CS1; m_current_cs_ul = CS1;
} }
if (!mcs_is_gprs(m_current_cs_dl)) { if (!mcs_is_gprs(m_current_cs_dl)) {
m_current_cs_dl = GprsCodingScheme::getGprsByNum( m_current_cs_dl = mcs_get_gprs_by_num(
m_bts->bts_data()->initial_cs_dl); m_bts->bts_data()->initial_cs_dl);
if (!m_current_cs_dl.isValid()) if (!mcs_is_valid(m_current_cs_dl))
m_current_cs_dl = CS1; m_current_cs_dl = CS1;
} }
break; break;
@ -242,15 +243,15 @@ void GprsMs::set_mode(enum mcs_kind mode)
case EGPRS_GMSK: case EGPRS_GMSK:
case EGPRS: case EGPRS:
if (!mcs_is_edge(m_current_cs_ul)) { if (!mcs_is_edge(m_current_cs_ul)) {
m_current_cs_ul = GprsCodingScheme::getEgprsByNum( m_current_cs_ul = mcs_get_egprs_by_num(
m_bts->bts_data()->initial_mcs_ul); m_bts->bts_data()->initial_mcs_ul);
if (!m_current_cs_ul.isValid()) if (!mcs_is_valid(m_current_cs_ul))
m_current_cs_ul = MCS1; m_current_cs_ul = MCS1;
} }
if (!mcs_is_edge(m_current_cs_dl)) { if (!mcs_is_edge(m_current_cs_dl)) {
m_current_cs_dl = GprsCodingScheme::getEgprsByNum( m_current_cs_dl = mcs_get_egprs_by_num(
m_bts->bts_data()->initial_mcs_dl); m_bts->bts_data()->initial_mcs_dl);
if (!m_current_cs_dl.isValid()) if (!mcs_is_valid(m_current_cs_dl))
m_current_cs_dl = MCS1; m_current_cs_dl = MCS1;
} }
break; break;
@ -510,7 +511,7 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate)
{ {
struct gprs_rlcmac_bts *bts_data; struct gprs_rlcmac_bts *bts_data;
int64_t now; int64_t now;
GprsCodingScheme max_cs_dl = this->max_cs_dl(); enum CodingScheme max_cs_dl = this->max_cs_dl();
OSMO_ASSERT(max_cs_dl); OSMO_ASSERT(max_cs_dl);
bts_data = m_bts->bts_data(); bts_data = m_bts->bts_data();
@ -527,7 +528,7 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate)
if (error_rate > bts_data->cs_adj_upper_limit) { if (error_rate > bts_data->cs_adj_upper_limit) {
if (mcs_chan_code(m_current_cs_dl) > 0) { if (mcs_chan_code(m_current_cs_dl) > 0) {
m_current_cs_dl.dec(mode()); mcs_dec_kind(&m_current_cs_dl, mode());
LOGP(DRLCMACDL, LOGL_INFO, LOGP(DRLCMACDL, LOGL_INFO,
"MS (IMSI %s): High error rate %d%%, " "MS (IMSI %s): High error rate %d%%, "
"reducing CS level to %s\n", "reducing CS level to %s\n",
@ -537,7 +538,7 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate)
} else if (error_rate < bts_data->cs_adj_lower_limit) { } else if (error_rate < bts_data->cs_adj_lower_limit) {
if (m_current_cs_dl < max_cs_dl) { if (m_current_cs_dl < max_cs_dl) {
if (now - m_last_cs_not_low > 1000) { if (now - m_last_cs_not_low > 1000) {
m_current_cs_dl.inc(mode()); mcs_inc_kind(&m_current_cs_dl, mode());
LOGP(DRLCMACDL, LOGL_INFO, LOGP(DRLCMACDL, LOGL_INFO,
"MS (IMSI %s): Low error rate %d%%, " "MS (IMSI %s): Low error rate %d%%, "
@ -560,7 +561,7 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate)
} }
} }
GprsCodingScheme GprsMs::max_cs_ul() const enum CodingScheme GprsMs::max_cs_ul() const
{ {
struct gprs_rlcmac_bts *bts_data; struct gprs_rlcmac_bts *bts_data;
@ -568,29 +569,30 @@ GprsCodingScheme GprsMs::max_cs_ul() const
bts_data = m_bts->bts_data(); bts_data = m_bts->bts_data();
if (mcs_is_gprs(m_current_cs_ul)) { if (mcs_is_gprs(m_current_cs_ul)) {
if (!bts_data->max_cs_ul) if (!bts_data->max_cs_ul) {
return GprsCodingScheme(CS4); return CS4;
}
return GprsCodingScheme::getGprsByNum(bts_data->max_cs_ul); return mcs_get_gprs_by_num(bts_data->max_cs_ul);
} }
if (!mcs_is_edge(m_current_cs_ul)) if (!mcs_is_edge(m_current_cs_ul))
return GprsCodingScheme(); /* UNKNOWN */ return UNKNOWN;
if (bts_data->max_mcs_ul) if (bts_data->max_mcs_ul)
return GprsCodingScheme::getEgprsByNum(bts_data->max_mcs_ul); return mcs_get_egprs_by_num(bts_data->max_mcs_ul);
else if (bts_data->max_cs_ul) else if (bts_data->max_cs_ul)
return GprsCodingScheme::getEgprsByNum(bts_data->max_cs_ul); return mcs_get_egprs_by_num(bts_data->max_cs_ul);
return GprsCodingScheme(MCS4); return MCS4;
} }
void GprsMs::set_current_cs_dl(CodingScheme scheme) void GprsMs::set_current_cs_dl(enum CodingScheme scheme)
{ {
m_current_cs_dl = scheme; m_current_cs_dl = scheme;
} }
GprsCodingScheme GprsMs::max_cs_dl() const enum CodingScheme GprsMs::max_cs_dl() const
{ {
struct gprs_rlcmac_bts *bts_data; struct gprs_rlcmac_bts *bts_data;
@ -598,32 +600,33 @@ GprsCodingScheme GprsMs::max_cs_dl() const
bts_data = m_bts->bts_data(); bts_data = m_bts->bts_data();
if (mcs_is_gprs(m_current_cs_dl)) { if (mcs_is_gprs(m_current_cs_dl)) {
if (!bts_data->max_cs_dl) if (!bts_data->max_cs_dl) {
return GprsCodingScheme(CS4); return CS4;
}
return GprsCodingScheme::getGprsByNum(bts_data->max_cs_dl); return mcs_get_gprs_by_num(bts_data->max_cs_dl);
} }
if (!mcs_is_edge(m_current_cs_dl)) if (!mcs_is_edge(m_current_cs_dl))
return GprsCodingScheme(); /* UNKNOWN */ return UNKNOWN;
if (bts_data->max_mcs_dl) if (bts_data->max_mcs_dl)
return GprsCodingScheme::getEgprsByNum(bts_data->max_mcs_dl); return mcs_get_egprs_by_num(bts_data->max_mcs_dl);
else if (bts_data->max_cs_dl) else if (bts_data->max_cs_dl)
return GprsCodingScheme::getEgprsByNum(bts_data->max_cs_dl); return mcs_get_egprs_by_num(bts_data->max_cs_dl);
return GprsCodingScheme(MCS4); return MCS4;
} }
void GprsMs::update_cs_ul(const pcu_l1_meas *meas) void GprsMs::update_cs_ul(const pcu_l1_meas *meas)
{ {
struct gprs_rlcmac_bts *bts_data; struct gprs_rlcmac_bts *bts_data;
GprsCodingScheme max_cs_ul = this->max_cs_ul(); enum CodingScheme max_cs_ul = this->max_cs_ul();
int old_link_qual; int old_link_qual;
int low; int low;
int high; int high;
GprsCodingScheme new_cs_ul = m_current_cs_ul; enum CodingScheme new_cs_ul = m_current_cs_ul;
uint8_t current_cs = mcs_chan_code(m_current_cs_ul); uint8_t current_cs = mcs_chan_code(m_current_cs_ul);
bts_data = m_bts->bts_data(); bts_data = m_bts->bts_data();
@ -674,10 +677,10 @@ void GprsMs::update_cs_ul(const pcu_l1_meas *meas)
old_link_qual = meas->link_qual; old_link_qual = meas->link_qual;
if (meas->link_qual < low && old_link_qual < low) if (meas->link_qual < low && old_link_qual < low)
new_cs_ul.dec(mode()); mcs_dec_kind(&new_cs_ul, mode());
else if (meas->link_qual > high && old_link_qual > high && else if (meas->link_qual > high && old_link_qual > high &&
m_current_cs_ul < max_cs_ul) m_current_cs_ul < max_cs_ul)
new_cs_ul.inc(mode()); mcs_inc_kind(&new_cs_ul, mode());
if (m_current_cs_ul != new_cs_ul) { if (m_current_cs_ul != new_cs_ul) {
LOGP(DRLCMACMEAS, LOGL_INFO, LOGP(DRLCMACMEAS, LOGL_INFO,
@ -724,9 +727,9 @@ void GprsMs::update_l1_meas(const pcu_l1_meas *meas)
} }
} }
GprsCodingScheme GprsMs::current_cs_dl() const enum CodingScheme GprsMs::current_cs_dl() const
{ {
GprsCodingScheme cs = m_current_cs_dl; enum CodingScheme cs = m_current_cs_dl;
size_t unencoded_octets; size_t unencoded_octets;
if (!m_bts) if (!m_bts)
@ -747,11 +750,11 @@ GprsCodingScheme GprsMs::current_cs_dl() const
return cs; return cs;
/* The throughput would probably be better if the CS level was reduced */ /* The throughput would probably be better if the CS level was reduced */
cs.dec(mode()); mcs_dec_kind(&cs, mode());
/* CS-2 doesn't gain throughput with small packets, further reduce to CS-1 */ /* CS-2 doesn't gain throughput with small packets, further reduce to CS-1 */
if (cs == GprsCodingScheme(CS2)) if (cs == CS2)
cs.dec(mode()); mcs_dec_kind(&cs, mode());
return cs; return cs;
} }

View File

@ -22,17 +22,17 @@
struct gprs_codel; struct gprs_codel;
#include <gprs_coding_scheme.h>
#include "cxx_linuxlist.h" #include "cxx_linuxlist.h"
#include "llc.h" #include "llc.h"
#include "tbf.h" #include "tbf.h"
#include "tbf_dl.h" #include "tbf_dl.h"
#include "pcu_l1_if.h" #include "pcu_l1_if.h"
#include <gprs_coding_scheme.h>
extern "C" { extern "C" {
#include <osmocom/core/timer.h> #include <osmocom/core/timer.h>
#include <osmocom/core/linuxlist.h> #include <osmocom/core/linuxlist.h>
#include "coding_scheme.h"
} }
#include <stdint.h> #include <stdint.h>
@ -87,12 +87,12 @@ public:
uint8_t egprs_ms_class() const; uint8_t egprs_ms_class() const;
void set_ms_class(uint8_t ms_class); void set_ms_class(uint8_t ms_class);
void set_egprs_ms_class(uint8_t ms_class); void set_egprs_ms_class(uint8_t ms_class);
void set_current_cs_dl(CodingScheme scheme); void set_current_cs_dl(enum CodingScheme scheme);
GprsCodingScheme current_cs_ul() const; enum CodingScheme current_cs_ul() const;
GprsCodingScheme current_cs_dl() const; enum CodingScheme current_cs_dl() const;
GprsCodingScheme max_cs_ul() const; enum CodingScheme max_cs_ul() const;
GprsCodingScheme max_cs_dl() const; enum CodingScheme max_cs_dl() const;
int first_common_ts() const; int first_common_ts() const;
uint8_t dl_slots() const; uint8_t dl_slots() const;
@ -164,8 +164,8 @@ private:
uint8_t m_ms_class; uint8_t m_ms_class;
uint8_t m_egprs_ms_class; uint8_t m_egprs_ms_class;
/* current coding scheme */ /* current coding scheme */
GprsCodingScheme m_current_cs_ul; enum CodingScheme m_current_cs_ul;
GprsCodingScheme m_current_cs_dl; enum CodingScheme m_current_cs_dl;
gprs_llc_queue m_llc_queue; gprs_llc_queue m_llc_queue;
@ -235,7 +235,7 @@ inline uint8_t GprsMs::egprs_ms_class() const
return m_egprs_ms_class; return m_egprs_ms_class;
} }
inline GprsCodingScheme GprsMs::current_cs_ul() const inline enum CodingScheme GprsMs::current_cs_ul() const
{ {
return m_current_cs_ul; return m_current_cs_ul;
} }

View File

@ -31,12 +31,12 @@
#include <signal.h> #include <signal.h>
#include <sched.h> #include <sched.h>
#include <bts.h> #include <bts.h>
#include <gprs_coding_scheme.h>
#include <osmocom/pcu/pcuif_proto.h> #include <osmocom/pcu/pcuif_proto.h>
#include "gprs_bssgp_pcu.h" #include "gprs_bssgp_pcu.h"
extern "C" { extern "C" {
#include "pcu_vty.h" #include "pcu_vty.h"
#include "coding_scheme.h"
#include <osmocom/gprs/gprs_bssgp.h> #include <osmocom/gprs/gprs_bssgp.h>
#include <osmocom/gprs/gprs_ns.h> #include <osmocom/gprs/gprs_ns.h>
#include <osmocom/vty/telnet_interface.h> #include <osmocom/vty/telnet_interface.h>

View File

@ -27,7 +27,6 @@
#include "gprs_ms_storage.h" #include "gprs_ms_storage.h"
#include "gprs_ms.h" #include "gprs_ms.h"
#include "cxx_linuxlist.h" #include "cxx_linuxlist.h"
#include <gprs_coding_scheme.h>
#include <llc.h> #include <llc.h>
#include <pcu_l1_if.h> #include <pcu_l1_if.h>
#include <rlc.h> #include <rlc.h>

View File

@ -25,7 +25,7 @@
#include <encoding.h> #include <encoding.h>
#include <gprs_rlcmac.h> #include <gprs_rlcmac.h>
#include <gprs_debug.h> #include <gprs_debug.h>
#include <gprs_coding_scheme.h> #include <coding_scheme.h>
#include <gprs_ms.h> #include <gprs_ms.h>
#include <gprs_ms_storage.h> #include <gprs_ms_storage.h>
#include <pcu_l1_if.h> #include <pcu_l1_if.h>
@ -688,11 +688,11 @@ void gprs_rlcmac_pdch::rcv_measurement_report(Packet_Measurement_Report_t *repor
/* Received Uplink RLC control block. */ /* Received Uplink RLC control block. */
int gprs_rlcmac_pdch::rcv_control_block(const uint8_t *data, uint8_t data_len, int gprs_rlcmac_pdch::rcv_control_block(const uint8_t *data, uint8_t data_len,
uint32_t fn, struct pcu_l1_meas *meas, GprsCodingScheme cs) uint32_t fn, struct pcu_l1_meas *meas, enum CodingScheme cs)
{ {
bitvec *rlc_block; bitvec *rlc_block;
RlcMacUplink_t *ul_control_block; RlcMacUplink_t *ul_control_block;
unsigned len = cs.maxBytesUL(); unsigned len = mcs_max_bytes_ul(cs);
int rc; int rc;
if (!(rlc_block = bitvec_alloc(len, tall_pcu_ctx))) if (!(rlc_block = bitvec_alloc(len, tall_pcu_ctx)))
@ -751,7 +751,7 @@ free_ret:
int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn, int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn,
struct pcu_l1_meas *meas) struct pcu_l1_meas *meas)
{ {
GprsCodingScheme cs = GprsCodingScheme::getBySizeUL(len); enum CodingScheme cs = mcs_get_by_size_ul(len);
if (!cs) { if (!cs) {
bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS); bts()->do_rate_ctr_inc(CTR_DECODE_ERRORS);
LOGP(DRLCMACUL, LOGL_ERROR, "Dropping data block with invalid" LOGP(DRLCMACUL, LOGL_ERROR, "Dropping data block with invalid"
@ -762,7 +762,7 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn,
bts()->do_rate_ctr_add(CTR_RLC_UL_BYTES, len); bts()->do_rate_ctr_add(CTR_RLC_UL_BYTES, len);
LOGP(DRLCMACUL, LOGL_DEBUG, "Got RLC block, coding scheme: %s, " LOGP(DRLCMACUL, LOGL_DEBUG, "Got RLC block, coding scheme: %s, "
"length: %d (%d))\n", mcs_name(cs), len, cs.usedSizeUL()); "length: %d (%d))\n", mcs_name(cs), len, mcs_used_size_ul(cs));
if (mcs_is_gprs(cs)) if (mcs_is_gprs(cs))
return rcv_block_gprs(data, len, fn, meas, cs); return rcv_block_gprs(data, len, fn, meas, cs);
@ -778,12 +778,12 @@ int gprs_rlcmac_pdch::rcv_block(uint8_t *data, uint8_t len, uint32_t fn,
/*! \brief process egprs and gprs data blocks */ /*! \brief process egprs and gprs data blocks */
int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t fn, int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t fn,
struct pcu_l1_meas *meas, GprsCodingScheme cs) struct pcu_l1_meas *meas, enum CodingScheme cs)
{ {
int rc; int rc;
struct gprs_rlc_data_info rlc_dec; struct gprs_rlc_data_info rlc_dec;
struct gprs_rlcmac_ul_tbf *tbf; struct gprs_rlcmac_ul_tbf *tbf;
unsigned len = cs.sizeUL(); unsigned len = mcs_size_ul(cs);
/* These are always data blocks, since EGPRS still uses CS-1 for /* These are always data blocks, since EGPRS still uses CS-1 for
* control blocks (see 44.060, section 10.3, 1st par.) * control blocks (see 44.060, section 10.3, 1st par.)
@ -836,7 +836,7 @@ int gprs_rlcmac_pdch::rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t f
} }
int gprs_rlcmac_pdch::rcv_block_gprs(uint8_t *data, uint8_t data_len, uint32_t fn, int gprs_rlcmac_pdch::rcv_block_gprs(uint8_t *data, uint8_t data_len, uint32_t fn,
struct pcu_l1_meas *meas, GprsCodingScheme cs) struct pcu_l1_meas *meas, enum CodingScheme cs)
{ {
unsigned payload = data[0] >> 6; unsigned payload = data[0] >> 6;
int rc = 0; int rc = 0;

View File

@ -25,9 +25,9 @@
extern "C" { extern "C" {
#include <osmocom/core/linuxlist.h> #include <osmocom/core/linuxlist.h>
#include "gsm_rlcmac.h" #include "gsm_rlcmac.h"
#include "coding_scheme.h"
} }
#include <gprs_coding_scheme.h>
#include <bts.h> #include <bts.h>
#endif #endif
@ -61,9 +61,9 @@ struct gprs_rlcmac_pdch {
int rcv_block(uint8_t *data, uint8_t len, uint32_t fn, int rcv_block(uint8_t *data, uint8_t len, uint32_t fn,
struct pcu_l1_meas *meas); struct pcu_l1_meas *meas);
int rcv_block_gprs(uint8_t *data, uint8_t data_len, uint32_t fn, int rcv_block_gprs(uint8_t *data, uint8_t data_len, uint32_t fn,
struct pcu_l1_meas *meas, GprsCodingScheme cs); struct pcu_l1_meas *meas, enum CodingScheme cs);
int rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t fn, int rcv_data_block(uint8_t *data, uint8_t data_len, uint32_t fn,
struct pcu_l1_meas *meas, GprsCodingScheme cs); struct pcu_l1_meas *meas, enum CodingScheme cs);
gprs_rlcmac_bts *bts_data() const; gprs_rlcmac_bts *bts_data() const;
BTS *bts() const; BTS *bts() const;
@ -113,7 +113,7 @@ struct gprs_rlcmac_pdch {
#ifdef __cplusplus #ifdef __cplusplus
private: private:
int rcv_control_block(const uint8_t *data, uint8_t data_len, uint32_t fn, int rcv_control_block(const uint8_t *data, uint8_t data_len, uint32_t fn,
struct pcu_l1_meas *meas, GprsCodingScheme cs); struct pcu_l1_meas *meas, enum CodingScheme cs);
void rcv_control_ack(Packet_Control_Acknowledgement_t *, uint32_t fn); void rcv_control_ack(Packet_Control_Acknowledgement_t *, uint32_t fn);
void rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *, uint32_t fn, struct pcu_l1_meas *meas); void rcv_control_dl_ack_nack(Packet_Downlink_Ack_Nack_t *, uint32_t fn, struct pcu_l1_meas *meas);

View File

@ -18,7 +18,6 @@
#include "bts.h" #include "bts.h"
#include "gprs_debug.h" #include "gprs_debug.h"
#include <gprs_coding_scheme.h>
#include <rlc.h> #include <rlc.h>
#include <stdbool.h> #include <stdbool.h>
@ -29,6 +28,8 @@ extern "C" {
#include <osmocom/core/utils.h> #include <osmocom/core/utils.h>
#include <osmocom/core/bitvec.h> #include <osmocom/core/bitvec.h>
#include <osmocom/core/logging.h> #include <osmocom/core/logging.h>
#include "coding_scheme.h"
} }
@ -314,11 +315,11 @@ bool gprs_rlc_ul_window::invalidate_bsn(const uint16_t bsn)
} }
static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc, static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc,
GprsCodingScheme cs, bool with_padding, unsigned int header_bits, enum CodingScheme cs, bool with_padding, unsigned int header_bits,
const unsigned int spb) const unsigned int spb)
{ {
unsigned int i; unsigned int i;
unsigned int padding_bits = with_padding ? cs.optionalPaddingBits() : 0; unsigned int padding_bits = with_padding ? mcs_opt_padding_bits(cs) : 0;
rlc->cs = cs; rlc->cs = cs;
rlc->r = 0; rlc->r = 0;
@ -330,7 +331,7 @@ static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc,
rlc->es_p = 0; rlc->es_p = 0;
rlc->rrbp = 0; rlc->rrbp = 0;
rlc->pr = 0; rlc->pr = 0;
rlc->num_data_blocks = num_data_blocks(cs.headerTypeData()); rlc->num_data_blocks = num_data_blocks(mcs_header_type(cs));
rlc->with_padding = with_padding; rlc->with_padding = with_padding;
OSMO_ASSERT(rlc->num_data_blocks <= ARRAY_SIZE(rlc->block_info)); OSMO_ASSERT(rlc->num_data_blocks <= ARRAY_SIZE(rlc->block_info));
@ -341,35 +342,35 @@ static void gprs_rlc_data_header_init(struct gprs_rlc_data_info *rlc,
rlc->data_offs_bits[i] = rlc->data_offs_bits[i] =
header_bits + padding_bits + header_bits + padding_bits +
(i+1) * num_data_block_header_bits(cs.headerTypeData()) + (i+1) * num_data_block_header_bits(mcs_header_type(cs)) +
i * 8 * rlc->block_info[0].data_len; i * 8 * rlc->block_info[0].data_len;
} }
} }
void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc, void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc,
GprsCodingScheme cs, bool with_padding, const unsigned int spb) enum CodingScheme cs, bool with_padding, const unsigned int spb)
{ {
return gprs_rlc_data_header_init(rlc, cs, with_padding, return gprs_rlc_data_header_init(rlc, cs, with_padding,
num_data_header_bits_DL(cs.headerTypeData()), spb); num_data_header_bits_DL(mcs_header_type(cs)), spb);
} }
void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc, void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc,
GprsCodingScheme cs, bool with_padding) enum CodingScheme cs, bool with_padding)
{ {
/* /*
* last parameter is sent as 0 since common function used * last parameter is sent as 0 since common function used
* for both DL and UL * for both DL and UL
*/ */
return gprs_rlc_data_header_init(rlc, cs, with_padding, return gprs_rlc_data_header_init(rlc, cs, with_padding,
num_data_header_bits_UL(cs.headerTypeData()), 0); num_data_header_bits_UL(mcs_header_type(cs)), 0);
} }
void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi,
GprsCodingScheme cs, bool with_padding, const unsigned int spb) enum CodingScheme cs, bool with_padding, const unsigned int spb)
{ {
unsigned int data_len = cs.maxDataBlockBytes(); unsigned int data_len = mcs_max_data_block_bytes(cs);
if (with_padding) if (with_padding)
data_len -= cs.optionalPaddingBits() / 8; data_len -= mcs_opt_padding_bits(cs) / 8;
rdbi->data_len = data_len; rdbi->data_len = data_len;
rdbi->bsn = 0; rdbi->bsn = 0;
@ -380,19 +381,19 @@ void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi,
rdbi->spb = spb; rdbi->spb = spb;
} }
unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, unsigned int gprs_rlc_mcs_cps(enum CodingScheme cs,
enum egprs_puncturing_values punct, enum egprs_puncturing_values punct,
enum egprs_puncturing_values punct2, bool with_padding) enum egprs_puncturing_values punct2, bool with_padding)
{ {
/* validate that punct and punct2 are as expected */ /* validate that punct and punct2 are as expected */
switch (CodingScheme(cs)) { switch (cs) {
case MCS9: case MCS9:
case MCS8: case MCS8:
case MCS7: case MCS7:
if (punct2 == EGPRS_PS_INVALID) { if (punct2 == EGPRS_PS_INVALID) {
LOGP(DRLCMACDL, LOGL_ERROR, LOGP(DRLCMACDL, LOGL_ERROR,
"Invalid punct2 value for coding scheme %d: %d\n", "Invalid punct2 value for coding scheme %d: %d\n",
CodingScheme(cs), punct2); cs, punct2);
return -1; return -1;
} }
/* fall through */ /* fall through */
@ -405,7 +406,7 @@ unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs,
if (punct == EGPRS_PS_INVALID) { if (punct == EGPRS_PS_INVALID) {
LOGP(DRLCMACDL, LOGL_ERROR, LOGP(DRLCMACDL, LOGL_ERROR,
"Invalid punct value for coding scheme %d: %d\n", "Invalid punct value for coding scheme %d: %d\n",
CodingScheme(cs), punct); cs, punct);
return -1; return -1;
} }
break; break;
@ -414,7 +415,7 @@ unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs,
} }
/* See 3GPP TS 44.060 10.4.8a.3.1, 10.4.8a.2.1, 10.4.8a.1.1 */ /* See 3GPP TS 44.060 10.4.8a.3.1, 10.4.8a.2.1, 10.4.8a.1.1 */
switch (CodingScheme(cs)) { switch (cs) {
case MCS1: return 0b1011 + case MCS1: return 0b1011 +
punct % EGPRS_MAX_PS_NUM_2; punct % EGPRS_MAX_PS_NUM_2;
case MCS2: return 0b1001 + case MCS2: return 0b1001 +
@ -443,12 +444,12 @@ unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs,
} }
void gprs_rlc_mcs_cps_decode(unsigned int cps, void gprs_rlc_mcs_cps_decode(unsigned int cps,
GprsCodingScheme cs, int *punct, int *punct2, int *with_padding) enum CodingScheme cs, int *punct, int *punct2, int *with_padding)
{ {
*punct2 = -1; *punct2 = -1;
*with_padding = 0; *with_padding = 0;
switch (CodingScheme(cs)) { switch (cs) {
case MCS1: case MCS1:
cps -= 0b1011; *punct = cps % 2; break; cps -= 0b1011; *punct = cps % 2; break;
case MCS2: case MCS2:
@ -481,8 +482,8 @@ void gprs_rlc_mcs_cps_decode(unsigned int cps,
*/ */
enum egprs_puncturing_values gprs_get_punct_scheme( enum egprs_puncturing_values gprs_get_punct_scheme(
enum egprs_puncturing_values punct, enum egprs_puncturing_values punct,
const GprsCodingScheme &cs, const enum CodingScheme &cs,
const GprsCodingScheme &cs_current, const enum CodingScheme &cs_current,
const enum egprs_rlcmac_dl_spb spb) const enum egprs_rlcmac_dl_spb spb)
{ {
@ -495,23 +496,23 @@ enum egprs_puncturing_values gprs_get_punct_scheme(
return punct; return punct;
/* TS 44.060 9.3.2.1.1 */ /* TS 44.060 9.3.2.1.1 */
if ((CodingScheme(cs) == MCS9) && if ((cs == MCS9) &&
(CodingScheme(cs_current) == MCS6)) { (cs_current == MCS6)) {
if ((punct == EGPRS_PS_1) || (punct == EGPRS_PS_3)) if ((punct == EGPRS_PS_1) || (punct == EGPRS_PS_3))
return EGPRS_PS_1; return EGPRS_PS_1;
else if (punct == EGPRS_PS_2) else if (punct == EGPRS_PS_2)
return EGPRS_PS_2; return EGPRS_PS_2;
} else if ((CodingScheme(cs) == MCS6) && } else if ((cs == MCS6) &&
(CodingScheme(cs_current) == MCS9)) { (cs_current == MCS9)) {
if (punct == EGPRS_PS_1) if (punct == EGPRS_PS_1)
return EGPRS_PS_3; return EGPRS_PS_3;
else if (punct == EGPRS_PS_2) else if (punct == EGPRS_PS_2)
return EGPRS_PS_2; return EGPRS_PS_2;
} else if ((CodingScheme(cs) == MCS7) && } else if ((cs == MCS7) &&
(CodingScheme(cs_current) == MCS5)) (cs_current == MCS5))
return EGPRS_PS_1; return EGPRS_PS_1;
else if ((CodingScheme(cs) == MCS5) && else if ((cs == MCS5) &&
(CodingScheme(cs_current) == MCS7)) (cs_current == MCS7))
return EGPRS_PS_2; return EGPRS_PS_2;
else if (cs != cs_current) else if (cs != cs_current)
return EGPRS_PS_1; return EGPRS_PS_1;
@ -532,9 +533,9 @@ enum egprs_puncturing_values gprs_get_punct_scheme(
* TS 44.060 10.4.8a.3.1, 10.4.8a.2.1, 10.4.8a.1.1 * TS 44.060 10.4.8a.3.1, 10.4.8a.2.1, 10.4.8a.1.1
*/ */
void gprs_update_punct_scheme(enum egprs_puncturing_values *punct, void gprs_update_punct_scheme(enum egprs_puncturing_values *punct,
const GprsCodingScheme &cs) const enum CodingScheme &cs)
{ {
switch (CodingScheme(cs)) { switch (cs) {
case MCS1 : case MCS1 :
case MCS2 : case MCS2 :
case MCS5 : case MCS5 :

View File

@ -19,7 +19,9 @@
*/ */
#pragma once #pragma once
#include "gprs_coding_scheme.h" extern "C" {
#include "coding_scheme.h"
}
#include <osmocom/core/endian.h> #include <osmocom/core/endian.h>
@ -154,7 +156,7 @@ struct gprs_rlc_data_block_info {
}; };
struct gprs_rlc_data_info { struct gprs_rlc_data_info {
GprsCodingScheme cs; enum CodingScheme cs;
unsigned int r; unsigned int r;
unsigned int si; unsigned int si;
unsigned int tfi; unsigned int tfi;
@ -192,15 +194,15 @@ struct gprs_rlc_data {
* 8.1.1.1 and Table 8.1.1.2 * 8.1.1.1 and Table 8.1.1.2
* For UL. cs_last shall be used everywhere. * For UL. cs_last shall be used everywhere.
*/ */
GprsCodingScheme cs_current_trans; enum CodingScheme cs_current_trans;
GprsCodingScheme cs_last; enum CodingScheme cs_last;
/* /*
* The MCS of initial transmission of a BSN * The MCS of initial transmission of a BSN
* This variable is used for split block * This variable is used for split block
* processing in DL * processing in DL
*/ */
GprsCodingScheme cs_init; enum CodingScheme cs_init;
/* puncturing scheme value to be used for next transmission*/ /* puncturing scheme value to be used for next transmission*/
enum egprs_puncturing_values next_ps; enum egprs_puncturing_values next_ps;
@ -212,21 +214,21 @@ struct gprs_rlc_data {
uint8_t *prepare(struct gprs_rlc_data *rlc, size_t block_data_length); uint8_t *prepare(struct gprs_rlc_data *rlc, size_t block_data_length);
void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc, void gprs_rlc_data_info_init_dl(struct gprs_rlc_data_info *rlc,
GprsCodingScheme cs, bool with_padding, const unsigned int spb); enum CodingScheme cs, bool with_padding, const unsigned int spb);
void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc, void gprs_rlc_data_info_init_ul(struct gprs_rlc_data_info *rlc,
GprsCodingScheme cs, bool with_padding); enum CodingScheme cs, bool with_padding);
void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi, void gprs_rlc_data_block_info_init(struct gprs_rlc_data_block_info *rdbi,
GprsCodingScheme cs, bool with_padding, const unsigned int spb); enum CodingScheme cs, bool with_padding, const unsigned int spb);
unsigned int gprs_rlc_mcs_cps(GprsCodingScheme cs, enum egprs_puncturing_values unsigned int gprs_rlc_mcs_cps(enum CodingScheme cs, enum egprs_puncturing_values
punct, enum egprs_puncturing_values punct2, bool with_padding); punct, enum egprs_puncturing_values punct2, bool with_padding);
void gprs_rlc_mcs_cps_decode(unsigned int cps, GprsCodingScheme cs, void gprs_rlc_mcs_cps_decode(unsigned int cps, enum CodingScheme cs,
int *punct, int *punct2, int *with_padding); int *punct, int *punct2, int *with_padding);
enum egprs_puncturing_values gprs_get_punct_scheme(enum egprs_puncturing_values enum egprs_puncturing_values gprs_get_punct_scheme(enum egprs_puncturing_values
punct, const GprsCodingScheme &cs, punct, const enum CodingScheme &cs,
const GprsCodingScheme &cs_current_trans, const enum CodingScheme &cs_current_trans,
const enum egprs_rlcmac_dl_spb spb); const enum egprs_rlcmac_dl_spb spb);
void gprs_update_punct_scheme(enum egprs_puncturing_values *punct, void gprs_update_punct_scheme(enum egprs_puncturing_values *punct,
const GprsCodingScheme &cs); const enum CodingScheme &cs);
/* /*
* I hold the currently transferred blocks and will provide * I hold the currently transferred blocks and will provide
* the routines to manipulate these arrays. * the routines to manipulate these arrays.

View File

@ -33,7 +33,6 @@
#include <pcu_utils.h> #include <pcu_utils.h>
#include <gprs_ms_storage.h> #include <gprs_ms_storage.h>
#include <sba.h> #include <sba.h>
#include <gprs_coding_scheme.h>
#include <gsm_timer.h> #include <gsm_timer.h>
#include <pdch.h> #include <pdch.h>
@ -49,6 +48,7 @@ extern "C" {
#include <osmocom/gsm/protocol/gsm_04_08.h> #include <osmocom/gsm/protocol/gsm_04_08.h>
#include "gsm_rlcmac.h" #include "gsm_rlcmac.h"
#include "coding_scheme.h"
} }
#include <errno.h> #include <errno.h>
@ -310,13 +310,14 @@ void gprs_rlcmac_tbf::set_ms_class(uint8_t ms_class_)
m_ms_class = ms_class_; m_ms_class = ms_class_;
} }
GprsCodingScheme gprs_rlcmac_tbf::current_cs() const enum CodingScheme gprs_rlcmac_tbf::current_cs() const
{ {
GprsCodingScheme cs; enum CodingScheme cs;
if (direction == GPRS_RLCMAC_UL_TBF) if (direction == GPRS_RLCMAC_UL_TBF)
cs = m_ms ? m_ms->current_cs_ul() : GprsCodingScheme(); cs = m_ms ? m_ms->current_cs_ul() : UNKNOWN;
else else
cs = m_ms ? m_ms->current_cs_dl() : GprsCodingScheme(); cs = m_ms ? m_ms->current_cs_dl() : UNKNOWN;
return cs; return cs;
} }
@ -965,8 +966,8 @@ static int ul_tbf_dtor(struct gprs_rlcmac_ul_tbf *tbf)
static void setup_egprs_mode(gprs_rlcmac_bts *bts, GprsMs *ms) static void setup_egprs_mode(gprs_rlcmac_bts *bts, GprsMs *ms)
{ {
if (mcs_is_edge_gmsk(GprsCodingScheme::getEgprsByNum(bts->max_mcs_ul)) && if (mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts->max_mcs_ul)) &&
mcs_is_edge_gmsk(GprsCodingScheme::getEgprsByNum(bts->max_mcs_dl)) && mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts->max_mcs_dl)) &&
ms->mode() != EGPRS) ms->mode() != EGPRS)
{ {
ms->set_mode(EGPRS_GMSK); ms->set_mode(EGPRS_GMSK);

View File

@ -24,14 +24,16 @@
#include "rlc.h" #include "rlc.h"
#include "cxx_linuxlist.h" #include "cxx_linuxlist.h"
#include <gprs_debug.h> #include <gprs_debug.h>
#include <gprs_coding_scheme.h>
#include <gsm_timer.h> #include <gsm_timer.h>
#include <stdint.h> #include <stdint.h>
extern "C" { extern "C" {
#include <osmocom/core/utils.h> #include <osmocom/core/utils.h>
#include <osmocom/core/linuxlist.h> #include <osmocom/core/linuxlist.h>
#include <osmocom/core/logging.h> #include <osmocom/core/logging.h>
#include <osmocom/core/timer.h> #include <osmocom/core/timer.h>
#include "coding_scheme.h"
} }
struct bssgp_bvc_ctx; struct bssgp_bvc_ctx;
@ -245,7 +247,7 @@ struct gprs_rlcmac_tbf {
void set_ta(uint8_t); void set_ta(uint8_t);
uint8_t ms_class() const; uint8_t ms_class() const;
void set_ms_class(uint8_t); void set_ms_class(uint8_t);
GprsCodingScheme current_cs() const; enum CodingScheme current_cs() const;
size_t llc_queue_size() const; size_t llc_queue_size() const;
time_t created_ts() const; time_t created_ts() const;

View File

@ -30,7 +30,6 @@
#include <gprs_codel.h> #include <gprs_codel.h>
#include <decoding.h> #include <decoding.h>
#include <encoding.h> #include <encoding.h>
#include <gprs_coding_scheme.h>
#include <gprs_ms.h> #include <gprs_ms.h>
#include <gprs_ms_storage.h> #include <gprs_ms_storage.h>
#include <llc.h> #include <llc.h>
@ -370,7 +369,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
{ {
int bsn; int bsn;
int data_len2, force_data_len = -1; int data_len2, force_data_len = -1;
GprsCodingScheme force_cs; enum CodingScheme force_cs = UNKNOWN;
/* search for a nacked or resend marked bsn */ /* search for a nacked or resend marked bsn */
bsn = m_window.resend_needed(); bsn = m_window.resend_needed();
@ -446,7 +445,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
return take_next_bsn(fn, previous_bsn, may_combine); return take_next_bsn(fn, previous_bsn, may_combine);
} else if (have_data()) { } else if (have_data()) {
/* The window has space left, generate new bsn */ /* The window has space left, generate new bsn */
GprsCodingScheme new_cs; enum CodingScheme new_cs;
new_cs = force_cs ? force_cs : current_cs(); new_cs = force_cs ? force_cs : current_cs();
LOGPTBFDL(this, LOGL_DEBUG, LOGPTBFDL(this, LOGL_DEBUG,
"Sending new block at BSN %d, CS=%s\n", "Sending new block at BSN %d, CS=%s\n",
@ -480,7 +479,7 @@ int gprs_rlcmac_dl_tbf::take_next_bsn(uint32_t fn,
bts->do_rate_ctr_inc(CTR_RLC_RESENT); bts->do_rate_ctr_inc(CTR_RLC_RESENT);
} }
*may_combine = num_data_blocks(m_rlc.block(bsn)->cs_current_trans.headerTypeData()) > 1; *may_combine = num_data_blocks(mcs_header_type(m_rlc.block(bsn)->cs_current_trans)) > 1;
return bsn; return bsn;
} }
@ -561,7 +560,7 @@ void gprs_rlcmac_dl_tbf::schedule_next_frame()
m_last_dl_drained_fn = -1; m_last_dl_drained_fn = -1;
} }
int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, GprsCodingScheme cs) int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, enum CodingScheme cs)
{ {
uint8_t *data; uint8_t *data;
gprs_rlc_data *rlc_data; gprs_rlc_data *rlc_data;
@ -574,10 +573,10 @@ int gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, GprsCodingScheme cs)
if (m_llc.frame_length() == 0) if (m_llc.frame_length() == 0)
schedule_next_frame(); schedule_next_frame();
OSMO_ASSERT(cs.isValid()); OSMO_ASSERT(mcs_is_valid(cs));
/* length of usable data block (single data unit w/o header) */ /* length of usable data block (single data unit w/o header) */
const uint8_t block_data_len = cs.maxDataBlockBytes(); const uint8_t block_data_len = mcs_max_data_block_bytes(cs);
/* now we still have untransmitted LLC data, so we fill mac block */ /* now we still have untransmitted LLC data, so we fill mac block */
rlc_data = m_rlc.block(bsn); rlc_data = m_rlc.block(bsn);
@ -691,7 +690,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
int rc; int rc;
bool is_final = false; bool is_final = false;
gprs_rlc_data_info rlc; gprs_rlc_data_info rlc;
GprsCodingScheme cs; enum CodingScheme cs;
int bsns[ARRAY_SIZE(rlc.block_info)]; int bsns[ARRAY_SIZE(rlc.block_info)];
unsigned num_bsns; unsigned num_bsns;
bool need_padding = false; bool need_padding = false;
@ -740,8 +739,8 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
* Refer commit be881c028fc4da00c4046ecd9296727975c206a3 * Refer commit be881c028fc4da00c4046ecd9296727975c206a3
* dated 2016-02-07 23:45:40 (UTC) * dated 2016-02-07 23:45:40 (UTC)
*/ */
if (cs != GprsCodingScheme(MCS8)) if (cs != MCS8)
cs.decToSingleBlock(&need_padding); mcs_dec_to_single_block(&cs, &need_padding);
} }
spb = get_egprs_dl_spb(index); spb = get_egprs_dl_spb(index);
@ -756,7 +755,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
rlc.tfi = m_tfi; /* TFI */ rlc.tfi = m_tfi; /* TFI */
/* return data block(s) as message */ /* return data block(s) as message */
msg_len = cs.sizeDL(); msg_len = mcs_size_dl(cs);
dl_msg = msgb_alloc(msg_len, "rlcmac_dl_data"); dl_msg = msgb_alloc(msg_len, "rlcmac_dl_data");
if (!dl_msg) if (!dl_msg)
return NULL; return NULL;
@ -1273,11 +1272,11 @@ enum egprs_rlc_dl_reseg_bsn_state
egprs_rlc_dl_reseg_bsn_state *block_status_dl = egprs_rlc_dl_reseg_bsn_state *block_status_dl =
&rlc_data->spb_status.block_status_dl; &rlc_data->spb_status.block_status_dl;
enum CodingScheme cs_init = CodingScheme(rlc_data->cs_init); enum CodingScheme cs_init = rlc_data->cs_init;
enum CodingScheme cs_current_trans = CodingScheme(rlc_data->cs_current_trans); enum CodingScheme cs_current_trans = rlc_data->cs_current_trans;
enum HeaderType ht_cs_init = rlc_data->cs_init.headerTypeData(); enum HeaderType ht_cs_init = mcs_header_type(rlc_data->cs_init);
enum HeaderType ht_cs_current_trans = rlc_data->cs_current_trans.headerTypeData(); enum HeaderType ht_cs_current_trans = mcs_header_type(rlc_data->cs_current_trans);
*block_data = &rlc_data->block[0]; *block_data = &rlc_data->block[0];
@ -1346,11 +1345,11 @@ enum egprs_rlcmac_dl_spb gprs_rlcmac_dl_tbf::get_egprs_dl_spb(const int bsn)
struct gprs_rlc_data *rlc_data = m_rlc.block(bsn); struct gprs_rlc_data *rlc_data = m_rlc.block(bsn);
egprs_rlc_dl_reseg_bsn_state block_status_dl = rlc_data->spb_status.block_status_dl; egprs_rlc_dl_reseg_bsn_state block_status_dl = rlc_data->spb_status.block_status_dl;
enum CodingScheme cs_init = CodingScheme(rlc_data->cs_init); enum CodingScheme cs_init = rlc_data->cs_init;
enum CodingScheme cs_current_trans = CodingScheme(rlc_data->cs_current_trans); enum CodingScheme cs_current_trans = rlc_data->cs_current_trans;
enum HeaderType ht_cs_init = rlc_data->cs_init.headerTypeData(); enum HeaderType ht_cs_init = mcs_header_type(rlc_data->cs_init);
enum HeaderType ht_cs_current_trans = rlc_data->cs_current_trans.headerTypeData(); enum HeaderType ht_cs_current_trans = mcs_header_type(rlc_data->cs_current_trans);
/* Table 10.4.8b.1 of 44.060 */ /* Table 10.4.8b.1 of 44.060 */
if (ht_cs_current_trans == HEADER_EGPRS_DATA_TYPE_3) { if (ht_cs_current_trans == HEADER_EGPRS_DATA_TYPE_3) {

View File

@ -111,7 +111,7 @@ protected:
int take_next_bsn(uint32_t fn, int previous_bsn, int take_next_bsn(uint32_t fn, int previous_bsn,
bool *may_combine); bool *may_combine);
bool restart_bsn_cycle(); bool restart_bsn_cycle();
int create_new_bsn(const uint32_t fn, GprsCodingScheme cs); int create_new_bsn(const uint32_t fn, enum CodingScheme cs);
struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts, struct msgb *create_dl_acked_block(const uint32_t fn, const uint8_t ts,
int index, int index2 = -1); int index, int index2 = -1);
int update_window(const uint8_t ssn, const uint8_t *rbb); int update_window(const uint8_t ssn, const uint8_t *rbb);

View File

@ -29,7 +29,6 @@
#include <gprs_bssgp_pcu.h> #include <gprs_bssgp_pcu.h>
#include <decoding.h> #include <decoding.h>
#include <pcu_l1_if.h> #include <pcu_l1_if.h>
#include <gprs_coding_scheme.h>
#include <gprs_ms.h> #include <gprs_ms.h>
#include <llc.h> #include <llc.h>
#include "pcu_utils.h" #include "pcu_utils.h"
@ -75,7 +74,7 @@ int gprs_rlcmac_ul_tbf::assemble_forward_llc(const gprs_rlc_data *_data)
const uint8_t *data = _data->block; const uint8_t *data = _data->block;
uint8_t len = _data->len; uint8_t len = _data->len;
const struct gprs_rlc_data_block_info *rdbi = &_data->block_info; const struct gprs_rlc_data_block_info *rdbi = &_data->block_info;
GprsCodingScheme cs = _data->cs_last; enum CodingScheme cs = _data->cs_last;
Decoding::RlcData frames[16], *frame; Decoding::RlcData frames[16], *frame;
int i, num_frames = 0; int i, num_frames = 0;
@ -523,7 +522,7 @@ egprs_rlc_ul_reseg_bsn_state gprs_rlcmac_ul_tbf::handle_egprs_ul_spb(
* upgrade the MCS to the type 2 * upgrade the MCS to the type 2
*/ */
if (assemble_status == EGPRS_RESEG_DEFAULT) { if (assemble_status == EGPRS_RESEG_DEFAULT) {
switch (CodingScheme(rlc->cs)) { switch (rlc->cs) {
case MCS3 : case MCS3 :
block->cs_last = MCS6; block->cs_last = MCS6;
LOGPTBFUL(this, LOGL_DEBUG, "Upgrading to MCS6\n"); LOGPTBFUL(this, LOGL_DEBUG, "Upgrading to MCS6\n");

View File

@ -21,7 +21,6 @@
*/ */
#include "gprs_debug.h" #include "gprs_debug.h"
#include "gprs_coding_scheme.h"
#include "decoding.h" #include "decoding.h"
#include "encoding.h" #include "encoding.h"
#include "rlc.h" #include "rlc.h"
@ -31,6 +30,7 @@
extern "C" { extern "C" {
#include "pcu_vty.h" #include "pcu_vty.h"
#include "coding_scheme.h"
#include <osmocom/core/application.h> #include <osmocom/core/application.h>
#include <osmocom/core/msgb.h> #include <osmocom/core/msgb.h>
@ -48,69 +48,69 @@ void *tall_pcu_ctx;
int16_t spoof_mnc = 0, spoof_mcc = 0; int16_t spoof_mnc = 0, spoof_mcc = 0;
bool spoof_mnc_3_digits = false; bool spoof_mnc_3_digits = false;
static void check_coding_scheme(GprsCodingScheme& cs, enum mcs_kind mode) static void check_coding_scheme(enum CodingScheme& cs, enum mcs_kind mode)
{ {
volatile unsigned expected_size; volatile unsigned expected_size;
bool need_padding; bool need_padding;
GprsCodingScheme new_cs; enum CodingScheme new_cs;
OSMO_ASSERT(cs.isValid()); OSMO_ASSERT(mcs_is_valid(cs));
OSMO_ASSERT(cs.isCompatible(mode)); OSMO_ASSERT(mcs_is_compat_kind(cs, mode));
/* Check static getBySizeUL() */ /* Check static getBySizeUL() */
expected_size = cs.usedSizeUL(); expected_size = mcs_used_size_ul(cs);
if (cs.spareBitsUL() > 0 && mcs_is_gprs(cs)) if (mcs_spare_bits_ul(cs) > 0 && mcs_is_gprs(cs))
expected_size += 1; expected_size += 1;
OSMO_ASSERT(expected_size == cs.sizeUL()); OSMO_ASSERT(expected_size == mcs_size_ul(cs));
OSMO_ASSERT(cs == GprsCodingScheme::getBySizeUL(expected_size)); OSMO_ASSERT(cs == mcs_get_by_size_ul(expected_size));
/* Check static sizeUL() */ /* Check static sizeUL() */
expected_size = cs.usedSizeDL(); expected_size = mcs_used_size_dl(cs);
if (cs.spareBitsDL() > 0 && mcs_is_gprs(cs)) if (mcs_spare_bits_dl(cs) > 0 && mcs_is_gprs(cs))
expected_size += 1; expected_size += 1;
OSMO_ASSERT(expected_size == cs.sizeDL()); OSMO_ASSERT(expected_size == mcs_size_dl(cs));
/* Check data block sizes */ /* Check data block sizes */
OSMO_ASSERT(cs.maxDataBlockBytes() * num_data_blocks(cs.headerTypeData()) < cs.maxBytesDL()); OSMO_ASSERT(mcs_max_data_block_bytes(cs) * num_data_blocks(mcs_header_type(cs)) < mcs_max_bytes_dl(cs));
OSMO_ASSERT(cs.maxDataBlockBytes() * num_data_blocks(cs.headerTypeData()) < cs.maxBytesUL()); OSMO_ASSERT(mcs_max_data_block_bytes(cs) * num_data_blocks(mcs_header_type(cs)) < mcs_max_bytes_ul(cs));
/* Check inc/dec */ /* Check inc/dec */
new_cs = cs; new_cs = cs;
new_cs.inc(mode); mcs_inc_kind(&new_cs, mode);
OSMO_ASSERT(new_cs.isCompatible(mode)); OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));
if (new_cs != cs) { if (new_cs != cs) {
new_cs.dec(mode); mcs_dec_kind(&new_cs, mode);
OSMO_ASSERT(new_cs.isCompatible(mode)); OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));
OSMO_ASSERT(new_cs == cs); OSMO_ASSERT(new_cs == cs);
} }
new_cs.dec(mode); mcs_dec_kind(&new_cs, mode);
OSMO_ASSERT(new_cs.isCompatible(mode)); OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));
if (new_cs != cs) { if (new_cs != cs) {
new_cs.inc(mode); mcs_inc_kind(&new_cs, mode);
OSMO_ASSERT(new_cs.isCompatible(mode)); OSMO_ASSERT(mcs_is_compat_kind(new_cs, mode));
OSMO_ASSERT(new_cs == cs); OSMO_ASSERT(new_cs == cs);
} }
new_cs = cs; new_cs = cs;
new_cs.decToSingleBlock(&need_padding); mcs_dec_to_single_block(&new_cs, &need_padding);
OSMO_ASSERT(new_cs.isFamilyCompatible(cs)); OSMO_ASSERT(mcs_is_family_compat(new_cs, cs));
OSMO_ASSERT(cs.isFamilyCompatible(new_cs)); OSMO_ASSERT(mcs_is_family_compat(cs, new_cs));
OSMO_ASSERT(cs.isCompatible(new_cs)); OSMO_ASSERT(mcs_is_compat(cs, new_cs));
if (need_padding) { if (need_padding) {
OSMO_ASSERT(new_cs.maxDataBlockBytes() == OSMO_ASSERT(mcs_max_data_block_bytes(new_cs) ==
new_cs.optionalPaddingBits()/8 + cs.maxDataBlockBytes()); mcs_opt_padding_bits(new_cs)/8 + mcs_max_data_block_bytes(cs));
} else { } else {
OSMO_ASSERT(new_cs.maxDataBlockBytes() == cs.maxDataBlockBytes()); OSMO_ASSERT(mcs_max_data_block_bytes(new_cs) == mcs_max_data_block_bytes(cs));
} }
} }
static bool check_strong_monotonicity(const GprsCodingScheme *cs, uint8_t last_UL, uint8_t last_DL) static bool check_strong_monotonicity(const enum CodingScheme cs, uint8_t last_UL, uint8_t last_DL)
{ {
if (cs->maxBytesUL() <= last_UL) if (mcs_max_bytes_ul(cs) <= last_UL)
return false; return false;
if (cs->maxBytesDL() <= last_DL) if (mcs_max_bytes_dl(cs) <= last_DL)
return false; return false;
return true; return true;
@ -121,14 +121,14 @@ static void test_coding_scheme()
unsigned i; unsigned i;
uint8_t last_size_UL; uint8_t last_size_UL;
uint8_t last_size_DL; uint8_t last_size_DL;
CodingScheme gprs_schemes[] = { enum CodingScheme gprs_schemes[] = {
CS1, CS1,
CS2, CS2,
CS3, CS3,
CS4 CS4
}; };
struct { struct {
CodingScheme s; enum CodingScheme s;
bool is_gmsk; bool is_gmsk;
} egprs_schemes[] = { } egprs_schemes[] = {
{ MCS1, true}, { MCS1, true},
@ -144,31 +144,28 @@ static void test_coding_scheme()
printf("=== start %s ===\n", __func__); printf("=== start %s ===\n", __func__);
GprsCodingScheme cs; enum CodingScheme cs = UNKNOWN;
OSMO_ASSERT(!cs); OSMO_ASSERT(!cs);
OSMO_ASSERT(CodingScheme(cs) == UNKNOWN); OSMO_ASSERT(!mcs_is_compat_kind(cs, GPRS));
OSMO_ASSERT(cs == GprsCodingScheme(UNKNOWN)); OSMO_ASSERT(!mcs_is_compat_kind(cs, EGPRS_GMSK));
OSMO_ASSERT(!cs.isCompatible(GPRS)); OSMO_ASSERT(!mcs_is_compat_kind(cs, EGPRS));
OSMO_ASSERT(!cs.isCompatible(EGPRS_GMSK));
OSMO_ASSERT(!cs.isCompatible(EGPRS));
last_size_UL = 0; last_size_UL = 0;
last_size_DL = 0; last_size_DL = 0;
for (i = 0; i < ARRAY_SIZE(gprs_schemes); i++) { for (i = 0; i < ARRAY_SIZE(gprs_schemes); i++) {
GprsCodingScheme current_cs(gprs_schemes[i]); enum CodingScheme current_cs = gprs_schemes[i];
OSMO_ASSERT(mcs_is_gprs(current_cs)); OSMO_ASSERT(mcs_is_gprs(current_cs));
OSMO_ASSERT(!mcs_is_edge(current_cs)); OSMO_ASSERT(!mcs_is_edge(current_cs));
OSMO_ASSERT(!mcs_is_edge_gmsk(current_cs)); OSMO_ASSERT(!mcs_is_edge_gmsk(current_cs));
OSMO_ASSERT(CodingScheme(current_cs) == gprs_schemes[i]); OSMO_ASSERT(current_cs == gprs_schemes[i]);
OSMO_ASSERT(current_cs == GprsCodingScheme(gprs_schemes[i]));
OSMO_ASSERT(check_strong_monotonicity(&current_cs, last_size_UL, last_size_DL)); OSMO_ASSERT(check_strong_monotonicity(current_cs, last_size_UL, last_size_DL));
last_size_UL = current_cs.maxBytesUL(); last_size_UL = mcs_max_bytes_ul(current_cs);
last_size_DL = current_cs.maxBytesDL(); last_size_DL = mcs_max_bytes_dl(current_cs);
/* Check header types */ /* Check header types */
OSMO_ASSERT(current_cs.headerTypeData() == HEADER_GPRS_DATA); OSMO_ASSERT(mcs_header_type(current_cs) == HEADER_GPRS_DATA);
check_coding_scheme(current_cs, GPRS); check_coding_scheme(current_cs, GPRS);
} }
@ -178,16 +175,15 @@ static void test_coding_scheme()
last_size_DL = 0; last_size_DL = 0;
for (i = 0; i < ARRAY_SIZE(egprs_schemes); i++) { for (i = 0; i < ARRAY_SIZE(egprs_schemes); i++) {
GprsCodingScheme current_cs(egprs_schemes[i].s); enum CodingScheme current_cs = egprs_schemes[i].s;
OSMO_ASSERT(!mcs_is_gprs(current_cs)); OSMO_ASSERT(!mcs_is_gprs(current_cs));
OSMO_ASSERT(mcs_is_edge(current_cs)); OSMO_ASSERT(mcs_is_edge(current_cs));
OSMO_ASSERT(mcs_is_edge_gmsk(current_cs) == !!egprs_schemes[i].is_gmsk); OSMO_ASSERT(mcs_is_edge_gmsk(current_cs) == !!egprs_schemes[i].is_gmsk);
OSMO_ASSERT(CodingScheme(current_cs) == egprs_schemes[i].s); OSMO_ASSERT(current_cs == egprs_schemes[i].s);
OSMO_ASSERT(current_cs == GprsCodingScheme(egprs_schemes[i].s));
OSMO_ASSERT(check_strong_monotonicity(&current_cs, last_size_UL, last_size_DL)); OSMO_ASSERT(check_strong_monotonicity(current_cs, last_size_UL, last_size_DL));
last_size_UL = current_cs.maxBytesUL(); last_size_UL = mcs_max_bytes_ul(current_cs);
last_size_DL = current_cs.maxBytesDL(); last_size_DL = mcs_max_bytes_dl(current_cs);
if (egprs_schemes[i].is_gmsk) if (egprs_schemes[i].is_gmsk)
check_coding_scheme(current_cs, EGPRS_GMSK); check_coding_scheme(current_cs, EGPRS_GMSK);
@ -201,7 +197,7 @@ static void test_coding_scheme()
static void test_rlc_unit_decoder() static void test_rlc_unit_decoder()
{ {
struct gprs_rlc_data_block_info rdbi = {0}; struct gprs_rlc_data_block_info rdbi = {0};
GprsCodingScheme cs; enum CodingScheme cs;
uint8_t data[74]; uint8_t data[74];
Decoding::RlcData chunks[16]; Decoding::RlcData chunks[16];
volatile int num_chunks = 0; volatile int num_chunks = 0;
@ -213,7 +209,7 @@ static void test_rlc_unit_decoder()
/* TS 44.060, B.1 */ /* TS 44.060, B.1 */
cs = CS4; cs = CS4;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 0; rdbi.e = 0;
rdbi.ti = 0; rdbi.ti = 0;
rdbi.cv = 15; rdbi.cv = 15;
@ -232,12 +228,12 @@ static void test_rlc_unit_decoder()
OSMO_ASSERT(chunks[1].length == 26); OSMO_ASSERT(chunks[1].length == 26);
OSMO_ASSERT(chunks[1].is_complete); OSMO_ASSERT(chunks[1].is_complete);
OSMO_ASSERT(chunks[2].offset == 39); OSMO_ASSERT(chunks[2].offset == 39);
OSMO_ASSERT(chunks[2].length == cs.maxDataBlockBytes() - 39); OSMO_ASSERT(chunks[2].length == mcs_max_data_block_bytes(cs) - 39);
OSMO_ASSERT(!chunks[2].is_complete); OSMO_ASSERT(!chunks[2].is_complete);
/* TS 44.060, B.2 */ /* TS 44.060, B.2 */
cs = CS1; cs = CS1;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 0; rdbi.e = 0;
rdbi.ti = 0; rdbi.ti = 0;
rdbi.cv = 15; rdbi.cv = 15;
@ -271,7 +267,7 @@ static void test_rlc_unit_decoder()
/* TS 44.060, B.3 */ /* TS 44.060, B.3 */
cs = CS1; cs = CS1;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 0; rdbi.e = 0;
rdbi.ti = 0; rdbi.ti = 0;
rdbi.cv = 15; rdbi.cv = 15;
@ -292,7 +288,7 @@ static void test_rlc_unit_decoder()
/* TS 44.060, B.4 */ /* TS 44.060, B.4 */
cs = CS1; cs = CS1;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 1; rdbi.e = 1;
rdbi.ti = 0; rdbi.ti = 0;
rdbi.cv = 15; rdbi.cv = 15;
@ -308,7 +304,7 @@ static void test_rlc_unit_decoder()
/* TS 44.060, B.6 */ /* TS 44.060, B.6 */
cs = CS1; cs = CS1;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 1; rdbi.e = 1;
rdbi.ti = 0; rdbi.ti = 0;
rdbi.cv = 0; rdbi.cv = 0;
@ -324,7 +320,7 @@ static void test_rlc_unit_decoder()
/* TS 44.060, B.8.1 */ /* TS 44.060, B.8.1 */
cs = MCS4; cs = MCS4;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 0; rdbi.e = 0;
rdbi.ti = 0; rdbi.ti = 0;
rdbi.cv = 15; rdbi.cv = 15;
@ -353,7 +349,7 @@ static void test_rlc_unit_decoder()
* is not consistent with Section 10.3a.1 & 10.3a.2. */ * is not consistent with Section 10.3a.1 & 10.3a.2. */
cs = MCS2; cs = MCS2;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 0; rdbi.e = 0;
rdbi.ti = 0; rdbi.ti = 0;
rdbi.cv = 15; rdbi.cv = 15;
@ -417,7 +413,7 @@ static void test_rlc_unit_decoder()
/* Note that the spec confuses the byte numbering here, too (see above) */ /* Note that the spec confuses the byte numbering here, too (see above) */
cs = MCS2; cs = MCS2;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 1; rdbi.e = 1;
rdbi.ti = 0; rdbi.ti = 0;
rdbi.cv = 0; rdbi.cv = 0;
@ -433,7 +429,7 @@ static void test_rlc_unit_decoder()
/* CS-1, TLLI, last block, single chunk until the end of the block */ /* CS-1, TLLI, last block, single chunk until the end of the block */
cs = CS1; cs = CS1;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 1; rdbi.e = 1;
rdbi.ti = 1; rdbi.ti = 1;
rdbi.cv = 0; rdbi.cv = 0;
@ -454,7 +450,7 @@ static void test_rlc_unit_decoder()
/* Like TS 44.060, B.2, first RLC block but with TLLI */ /* Like TS 44.060, B.2, first RLC block but with TLLI */
cs = CS1; cs = CS1;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 0; rdbi.e = 0;
rdbi.ti = 1; rdbi.ti = 1;
rdbi.cv = 15; rdbi.cv = 15;
@ -476,7 +472,7 @@ static void test_rlc_unit_decoder()
/* Like TS 44.060, B.8.1 but with TLLI */ /* Like TS 44.060, B.8.1 but with TLLI */
cs = MCS4; cs = MCS4;
rdbi.data_len = cs.maxDataBlockBytes(); rdbi.data_len = mcs_max_data_block_bytes(cs);
rdbi.e = 0; rdbi.e = 0;
rdbi.ti = 1; rdbi.ti = 1;
rdbi.cv = 15; rdbi.cv = 15;
@ -528,7 +524,7 @@ static void test_rlc_unit_decoder()
static void test_rlc_unit_encoder() static void test_rlc_unit_encoder()
{ {
struct gprs_rlc_data_block_info rdbi = {0}; struct gprs_rlc_data_block_info rdbi = {0};
GprsCodingScheme cs; enum CodingScheme cs;
uint8_t data[74]; uint8_t data[74];
uint8_t llc_data[1500] = {0,}; uint8_t llc_data[1500] = {0,};
int num_chunks = 0; int num_chunks = 0;
@ -1080,25 +1076,21 @@ static void test_rlc_unaligned_copy()
uint8_t saved_block[256]; uint8_t saved_block[256];
uint8_t test_block[256]; uint8_t test_block[256];
uint8_t out_block[256]; uint8_t out_block[256];
CodingScheme scheme; enum CodingScheme cs;
int pattern; int pattern;
volatile unsigned int block_idx, i; volatile unsigned int block_idx, i;
for (scheme = CS1; for (cs = CS1; cs < NUM_SCHEMES; cs = static_cast<enum CodingScheme>(cs + 1))
scheme < NUM_SCHEMES;
scheme = CodingScheme(scheme + 1))
{ {
GprsCodingScheme cs(scheme);
for (pattern = 0; pattern <= 0xff; pattern += 0xff) { for (pattern = 0; pattern <= 0xff; pattern += 0xff) {
/* prepare test block */ /* prepare test block */
test_block[0] = pattern ^ 0xff; test_block[0] = pattern ^ 0xff;
for (i = 1; i + 1 < cs.maxDataBlockBytes(); i++) for (i = 1; i + 1 < mcs_max_data_block_bytes(cs); i++)
test_block[i] = i; test_block[i] = i;
test_block[cs.maxDataBlockBytes()-1] = pattern ^ 0xff; test_block[mcs_max_data_block_bytes(cs)-1] = pattern ^ 0xff;
for (block_idx = 0; for (block_idx = 0;
block_idx < num_data_blocks(cs.headerTypeData()); block_idx < num_data_blocks(mcs_header_type(cs));
block_idx++) block_idx++)
{ {
struct gprs_rlc_data_info rlc; struct gprs_rlc_data_info rlc;
@ -1110,7 +1102,7 @@ static void test_rlc_unaligned_copy()
fprintf(stderr, fprintf(stderr,
"Test data block: %s\n", "Test data block: %s\n",
osmo_hexdump(test_block, cs.maxDataBlockBytes())); osmo_hexdump(test_block, mcs_max_data_block_bytes(cs)));
Encoding::rlc_copy_from_aligned_buffer( Encoding::rlc_copy_from_aligned_buffer(
&rlc, block_idx, bits, test_block); &rlc, block_idx, bits, test_block);
@ -1119,20 +1111,20 @@ static void test_rlc_unaligned_copy()
"Encoded message block, %s, idx %d, " "Encoded message block, %s, idx %d, "
"pattern %02x: %s\n", "pattern %02x: %s\n",
mcs_name(rlc.cs), block_idx, pattern, mcs_name(rlc.cs), block_idx, pattern,
osmo_hexdump(bits, cs.sizeDL())); osmo_hexdump(bits, mcs_size_dl(cs)));
Decoding::rlc_copy_to_aligned_buffer( Decoding::rlc_copy_to_aligned_buffer(
&rlc, block_idx, bits, out_block); &rlc, block_idx, bits, out_block);
fprintf(stderr, fprintf(stderr,
"Out data block: %s\n", "Out data block: %s\n",
osmo_hexdump(out_block, cs.maxDataBlockBytes())); osmo_hexdump(out_block, mcs_max_data_block_bytes(cs)));
/* restore original bits */ /* restore original bits */
Encoding::rlc_copy_from_aligned_buffer( Encoding::rlc_copy_from_aligned_buffer(
&rlc, block_idx, bits, saved_block); &rlc, block_idx, bits, saved_block);
OSMO_ASSERT(memcmp(test_block, out_block, OSMO_ASSERT(memcmp(test_block, out_block,
rlc.cs.maxDataBlockBytes()) == 0); mcs_max_data_block_bytes(rlc.cs)) == 0);
for (i = 0; i < sizeof(bits); i++) for (i = 0; i < sizeof(bits); i++)
OSMO_ASSERT(bits[i] == pattern); OSMO_ASSERT(bits[i] == pattern);
@ -1146,14 +1138,12 @@ static void test_rlc_info_init()
struct gprs_rlc_data_info rlc; struct gprs_rlc_data_info rlc;
printf("=== start %s ===\n", __func__); printf("=== start %s ===\n", __func__);
gprs_rlc_data_info_init_dl(&rlc, gprs_rlc_data_info_init_dl(&rlc, CS1, false, 0);
GprsCodingScheme(CS1), false, 0);
OSMO_ASSERT(rlc.num_data_blocks == 1); OSMO_ASSERT(rlc.num_data_blocks == 1);
OSMO_ASSERT(rlc.data_offs_bits[0] == 24); OSMO_ASSERT(rlc.data_offs_bits[0] == 24);
OSMO_ASSERT(rlc.block_info[0].data_len == 20); OSMO_ASSERT(rlc.block_info[0].data_len == 20);
gprs_rlc_data_info_init_dl(&rlc, gprs_rlc_data_info_init_dl(&rlc, MCS1, false, 0);
GprsCodingScheme(MCS1), false, 0);
OSMO_ASSERT(rlc.num_data_blocks == 1); OSMO_ASSERT(rlc.num_data_blocks == 1);
OSMO_ASSERT(rlc.data_offs_bits[0] == 33); OSMO_ASSERT(rlc.data_offs_bits[0] == 33);
OSMO_ASSERT(rlc.block_info[0].data_len == 22); OSMO_ASSERT(rlc.block_info[0].data_len == 22);
@ -1188,7 +1178,7 @@ static void uplink_header_type_2_parsing_test(BTS *the_bts,
tfi = 1; tfi = 1;
struct gprs_rlc_data_info rlc; struct gprs_rlc_data_info rlc;
GprsCodingScheme cs; enum CodingScheme cs;
int rc, offs; int rc, offs;
/*without padding*/ /*without padding*/
@ -1289,7 +1279,7 @@ static void uplink_header_type_1_parsing_test(BTS *the_bts,
uint8_t data[155] = {0}; uint8_t data[155] = {0};
struct gprs_rlc_ul_header_egprs_1 *egprs1 = NULL; struct gprs_rlc_ul_header_egprs_1 *egprs1 = NULL;
struct gprs_rlc_data_info rlc; struct gprs_rlc_data_info rlc;
GprsCodingScheme cs; enum CodingScheme cs;
int rc; int rc;
egprs1 = (struct gprs_rlc_ul_header_egprs_1 *) data; egprs1 = (struct gprs_rlc_ul_header_egprs_1 *) data;

View File

@ -32,6 +32,7 @@
extern "C" { extern "C" {
#include "pcu_vty.h" #include "pcu_vty.h"
#include "coding_scheme.h"
#include <osmocom/core/application.h> #include <osmocom/core/application.h>
#include <osmocom/core/msgb.h> #include <osmocom/core/msgb.h>
@ -656,7 +657,6 @@ static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,
gprs_rlcmac_bts *bts; gprs_rlcmac_bts *bts;
RlcMacUplink_t ulreq = {0}; RlcMacUplink_t ulreq = {0};
struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
GprsCodingScheme cs;
bts = the_bts->bts_data(); bts = the_bts->bts_data();
@ -732,7 +732,6 @@ static gprs_rlcmac_ul_tbf *puan_urbb_len_issue(BTS *the_bts,
* TS 44.060, B.8.1 * TS 44.060, B.8.1
* first seg received first, later second seg * first seg received first, later second seg
*/ */
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 0; egprs3->si = 0;
egprs3->r = 1; egprs3->r = 1;
@ -805,7 +804,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
gprs_rlcmac_bts *bts; gprs_rlcmac_bts *bts;
RlcMacUplink_t ulreq = {0}; RlcMacUplink_t ulreq = {0};
struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
GprsCodingScheme cs;
bts = the_bts->bts_data(); bts = the_bts->bts_data();
@ -882,7 +880,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
* TS 44.060, B.8.1 * TS 44.060, B.8.1
* first seg received first, later second seg * first seg received first, later second seg
*/ */
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -937,7 +934,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
*/ */
memset(data_msg, 0, sizeof(data_msg)); memset(data_msg, 0, sizeof(data_msg));
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -990,7 +986,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
* TS 44.060, B.8.1 * TS 44.060, B.8.1
* Error scenario with spb as 1 * Error scenario with spb as 1
*/ */
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -1027,7 +1022,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
for (i = 0; i < 42; i++) for (i = 0; i < 42; i++)
data_msg[i] = i; data_msg[i] = i;
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -1051,7 +1045,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
OSMO_ASSERT(block->spb_status.block_status_ul == OSMO_ASSERT(block->spb_status.block_status_ul ==
EGPRS_RESEG_FIRST_SEG_RXD); EGPRS_RESEG_FIRST_SEG_RXD);
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -1079,7 +1072,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
OSMO_ASSERT(block->cs_last == OSMO_ASSERT(block->cs_last ==
MCS6); MCS6);
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -1103,7 +1095,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
OSMO_ASSERT(block->spb_status.block_status_ul == OSMO_ASSERT(block->spb_status.block_status_ul ==
EGPRS_RESEG_FIRST_SEG_RXD); EGPRS_RESEG_FIRST_SEG_RXD);
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -1127,7 +1118,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
OSMO_ASSERT(block->spb_status.block_status_ul == OSMO_ASSERT(block->spb_status.block_status_ul ==
EGPRS_RESEG_FIRST_SEG_RXD); EGPRS_RESEG_FIRST_SEG_RXD);
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -1155,7 +1145,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
/* Assembled MCS is MCS6. so the size is 74 */ /* Assembled MCS is MCS6. so the size is 74 */
OSMO_ASSERT(block->len == 74); OSMO_ASSERT(block->len == 74);
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -1179,7 +1168,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_spb(BTS *the_bts,
OSMO_ASSERT(block->spb_status.block_status_ul == OSMO_ASSERT(block->spb_status.block_status_ul ==
EGPRS_RESEG_SECOND_SEG_RXD); EGPRS_RESEG_SECOND_SEG_RXD);
cs = MCS3;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 1; egprs3->si = 1;
egprs3->r = 1; egprs3->r = 1;
@ -1251,7 +1239,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf(BTS *the_bts,
gprs_rlcmac_ul_tbf *ul_tbf; gprs_rlcmac_ul_tbf *ul_tbf;
gprs_rlcmac_bts *bts; gprs_rlcmac_bts *bts;
RlcMacUplink_t ulreq = {0}; RlcMacUplink_t ulreq = {0};
GprsCodingScheme cs;
bts = the_bts->bts_data(); bts = the_bts->bts_data();
@ -1318,8 +1305,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_no_length(BTS *t
uint8_t trx_no = 0; uint8_t trx_no = 0;
int tfi = 0; int tfi = 0;
struct gprs_rlcmac_pdch *pdch; struct gprs_rlcmac_pdch *pdch;
GprsCodingScheme cs;
/* send fake data with cv=0*/ /* send fake data with cv=0*/
struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL; struct gprs_rlc_ul_header_egprs_3 *hdr3 = NULL;
@ -1400,7 +1385,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_URBB_with_length(BTS
uint8_t trx_no = 0; uint8_t trx_no = 0;
int tfi = 0; int tfi = 0;
struct gprs_rlcmac_pdch *pdch; struct gprs_rlcmac_pdch *pdch;
GprsCodingScheme cs;
check_tbf(ul_tbf); check_tbf(ul_tbf);
/* send fake data with cv=0*/ /* send fake data with cv=0*/
@ -1483,8 +1467,6 @@ static gprs_rlcmac_ul_tbf *establish_ul_tbf_two_phase_puan_CRBB(BTS *the_bts,
int tfi = 0; int tfi = 0;
gprs_rlcmac_ul_tbf *ul_tbf; gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_pdch *pdch; struct gprs_rlcmac_pdch *pdch;
GprsCodingScheme cs;
/* check the TBF */ /* check the TBF */
ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no); ul_tbf = the_bts->ul_tbf_by_tfi(tfi, trx_no, ts_no);
@ -2364,7 +2346,6 @@ static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,
gprs_rlcmac_bts *bts; gprs_rlcmac_bts *bts;
RlcMacUplink_t ulreq = {0}; RlcMacUplink_t ulreq = {0};
struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL; struct gprs_rlc_ul_header_egprs_3 *egprs3 = NULL;
GprsCodingScheme cs;
Packet_Resource_Request_t *presreq = NULL; Packet_Resource_Request_t *presreq = NULL;
MS_Radio_Access_capability_t *pmsradiocap = NULL; MS_Radio_Access_capability_t *pmsradiocap = NULL;
Multislot_capability_t *pmultislotcap = NULL; Multislot_capability_t *pmultislotcap = NULL;
@ -2429,7 +2410,6 @@ static gprs_rlcmac_ul_tbf *tbf_li_decoding(BTS *the_bts,
OSMO_ASSERT(ms->ta() == qta/4); OSMO_ASSERT(ms->ta() == qta/4);
OSMO_ASSERT(ms->ul_tbf() == ul_tbf); OSMO_ASSERT(ms->ul_tbf() == ul_tbf);
cs = MCS4;
egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg; egprs3 = (struct gprs_rlc_ul_header_egprs_3 *) data_msg;
egprs3->si = 0; egprs3->si = 0;
egprs3->r = 1; egprs3->r = 1;
@ -2817,7 +2797,7 @@ static void egprs_spb_to_normal_validation(BTS *the_bts,
OSMO_ASSERT(bsn1 == 0); OSMO_ASSERT(bsn1 == 0);
dl_tbf->ms()->set_current_cs_dl dl_tbf->ms()->set_current_cs_dl
(static_cast < CodingScheme > (static_cast < enum CodingScheme >
(CS4 + demanded_mcs)); (CS4 + demanded_mcs));
fn = fn_add_blocks(fn, 1); fn = fn_add_blocks(fn, 1);
@ -2849,7 +2829,7 @@ static void egprs_spb_to_normal_validation(BTS *the_bts,
/* Handle (MCS3, MCS3) -> MCS6 case */ /* Handle (MCS3, MCS3) -> MCS6 case */
dl_tbf->ms()->set_current_cs_dl dl_tbf->ms()->set_current_cs_dl
(static_cast < CodingScheme > (static_cast < enum CodingScheme >
(CS4 + mcs)); (CS4 + mcs));
NACK(dl_tbf, 0); NACK(dl_tbf, 0);
@ -2898,7 +2878,7 @@ static void establish_and_use_egprs_dl_tbf_for_spb(BTS *the_bts,
NACK(dl_tbf, 0); NACK(dl_tbf, 0);
dl_tbf->ms()->set_current_cs_dl dl_tbf->ms()->set_current_cs_dl
(static_cast < CodingScheme > (static_cast < enum CodingScheme >
(CS4 + demanded_mcs)); (CS4 + demanded_mcs));
fn = fn_add_blocks(fn, 1); fn = fn_add_blocks(fn, 1);
@ -2985,7 +2965,7 @@ static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
/* Set the demanded MCS to demanded_mcs */ /* Set the demanded MCS to demanded_mcs */
dl_tbf->ms()->set_current_cs_dl dl_tbf->ms()->set_current_cs_dl
(static_cast < CodingScheme > (static_cast < enum CodingScheme >
(CS4 + demanded_mcs)); (CS4 + demanded_mcs));
fn = fn_add_blocks(fn, 1); fn = fn_add_blocks(fn, 1);
@ -3012,7 +2992,7 @@ static void establish_and_use_egprs_dl_tbf_for_retx(BTS *the_bts,
NACK(dl_tbf, 1); NACK(dl_tbf, 1);
dl_tbf->ms()->set_current_cs_dl dl_tbf->ms()->set_current_cs_dl
(static_cast < CodingScheme > (static_cast < enum CodingScheme >
(CS4 + demanded_mcs)); (CS4 + demanded_mcs));
fn = fn_add_blocks(fn, 1); fn = fn_add_blocks(fn, 1);