Add header type 1 support for EGPRS uplink
Function is added to parse the EGPRS header type 1 in uplink tbf path. along with configuration parameter updation to reflect max mcs in UL Change-Id: I13c250e2e07377982ac3f29745f3cffd4088552a Reviewed-on: https://gerrit.osmocom.org/270 Reviewed-by: Harald Welte <laforge@gnumonks.org> Tested-by: Jenkins Builder
This commit is contained in:
parent
550a54184b
commit
99ab0a8fa0
|
@ -41,6 +41,8 @@ extern "C" {
|
||||||
|
|
||||||
#define LLC_CODEL_DISABLE 0
|
#define LLC_CODEL_DISABLE 0
|
||||||
#define LLC_CODEL_USE_DEFAULT (-1)
|
#define LLC_CODEL_USE_DEFAULT (-1)
|
||||||
|
#define MAX_GPRS_CS 9
|
||||||
|
|
||||||
|
|
||||||
struct BTS;
|
struct BTS;
|
||||||
struct GprsMs;
|
struct GprsMs;
|
||||||
|
@ -188,7 +190,7 @@ struct gprs_rlcmac_bts {
|
||||||
uint8_t cs_adj_enabled;
|
uint8_t cs_adj_enabled;
|
||||||
uint8_t cs_adj_upper_limit;
|
uint8_t cs_adj_upper_limit;
|
||||||
uint8_t cs_adj_lower_limit;
|
uint8_t cs_adj_lower_limit;
|
||||||
struct {int16_t low; int16_t high;} cs_lqual_ranges[4];
|
struct {int16_t low; int16_t high; } cs_lqual_ranges[MAX_GPRS_CS];
|
||||||
uint16_t cs_downgrade_threshold; /* downgrade if less packets left (DL) */
|
uint16_t cs_downgrade_threshold; /* downgrade if less packets left (DL) */
|
||||||
uint16_t ws_base;
|
uint16_t ws_base;
|
||||||
uint16_t ws_pdch; /* increase WS by this value per PDCH */
|
uint16_t ws_pdch; /* increase WS by this value per PDCH */
|
||||||
|
|
|
@ -357,8 +357,8 @@ int Decoding::rlc_parse_ul_data_header(struct gprs_rlc_data_info *rlc,
|
||||||
cur_bit = rlc_parse_ul_data_header_egprs_type_2(rlc, data, cs);
|
cur_bit = rlc_parse_ul_data_header_egprs_type_2(rlc, data, cs);
|
||||||
break;
|
break;
|
||||||
case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1 :
|
case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1 :
|
||||||
/* TODO: Support both header type 1 */
|
cur_bit = rlc_parse_ul_data_header_egprs_type_1(rlc, data, cs);
|
||||||
/* fall through */
|
break;
|
||||||
default:
|
default:
|
||||||
LOGP(DRLCMACDL, LOGL_ERROR,
|
LOGP(DRLCMACDL, LOGL_ERROR,
|
||||||
"Decoding of uplink %s data blocks not yet supported.\n",
|
"Decoding of uplink %s data blocks not yet supported.\n",
|
||||||
|
@ -455,6 +455,65 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_2(
|
||||||
return cur_bit;
|
return cur_bit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Decoding::rlc_parse_ul_data_header_egprs_type_1(
|
||||||
|
struct gprs_rlc_data_info *rlc,
|
||||||
|
const uint8_t *data, const GprsCodingScheme &cs)
|
||||||
|
{
|
||||||
|
struct gprs_rlc_ul_header_egprs_1 *egprs1;
|
||||||
|
unsigned int e_ti_header, cur_bit = 0, offs;
|
||||||
|
int punct, punct2, with_padding;
|
||||||
|
|
||||||
|
egprs1 = static_cast < struct gprs_rlc_ul_header_egprs_1 * >
|
||||||
|
((void *)data);
|
||||||
|
gprs_rlc_mcs_cps_decode(egprs1->cps, cs, &punct, &punct2,
|
||||||
|
&with_padding);
|
||||||
|
gprs_rlc_data_info_init_ul(rlc, cs, with_padding);
|
||||||
|
|
||||||
|
rlc->r = egprs1->r;
|
||||||
|
rlc->si = egprs1->si;
|
||||||
|
rlc->tfi = (egprs1->tfi_a << 0) | (egprs1->tfi_b << 2);
|
||||||
|
rlc->cps = egprs1->cps;
|
||||||
|
rlc->rsb = egprs1->rsb;
|
||||||
|
rlc->num_data_blocks = 2;
|
||||||
|
rlc->block_info[0].cv = egprs1->cv;
|
||||||
|
rlc->block_info[0].pi = egprs1->pi;
|
||||||
|
rlc->block_info[0].bsn =
|
||||||
|
(egprs1->bsn1_a << 0) | (egprs1->bsn1_b << 5);
|
||||||
|
|
||||||
|
cur_bit += rlc->data_offs_bits[0] - 2;
|
||||||
|
offs = rlc->data_offs_bits[0] / 8;
|
||||||
|
OSMO_ASSERT(rlc->data_offs_bits[0] % 8 == 0);
|
||||||
|
|
||||||
|
e_ti_header = data[offs - 1] >> 6;
|
||||||
|
rlc->block_info[0].e = (e_ti_header & 0x01);
|
||||||
|
rlc->block_info[0].ti = !!(e_ti_header & 0x02);
|
||||||
|
cur_bit += 2;
|
||||||
|
|
||||||
|
rlc->block_info[1].cv = egprs1->cv;
|
||||||
|
rlc->block_info[1].pi = egprs1->pi;
|
||||||
|
rlc->block_info[1].bsn = rlc->block_info[0].bsn +
|
||||||
|
((egprs1->bsn2_a << 0) | (egprs1->bsn2_b << 2));
|
||||||
|
rlc->block_info[1].bsn = rlc->block_info[1].bsn & (RLC_EGPRS_SNS - 1);
|
||||||
|
|
||||||
|
if ((rlc->block_info[1].bsn != rlc->block_info[0].bsn) &&
|
||||||
|
(rlc->block_info[0].cv == 0))
|
||||||
|
rlc->block_info[0].cv = 1;
|
||||||
|
|
||||||
|
cur_bit = rlc->data_offs_bits[1] - 2;
|
||||||
|
|
||||||
|
offs = rlc->data_offs_bits[1] / 8;
|
||||||
|
OSMO_ASSERT(rlc->data_offs_bits[1] % 8 == 2);
|
||||||
|
|
||||||
|
e_ti_header = (data[offs] & (0x03));
|
||||||
|
rlc->block_info[1].e = (e_ti_header & 0x01);
|
||||||
|
rlc->block_info[1].ti = !!(e_ti_header & 0x02);
|
||||||
|
cur_bit += 2;
|
||||||
|
/* skip data area */
|
||||||
|
cur_bit += cs.maxDataBlockBytes() * 8;
|
||||||
|
|
||||||
|
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 GprsCodingScheme &cs)
|
||||||
{
|
{
|
||||||
|
|
|
@ -52,6 +52,10 @@ public:
|
||||||
struct gprs_rlc_data_info *rlc,
|
struct gprs_rlc_data_info *rlc,
|
||||||
const uint8_t *data,
|
const uint8_t *data,
|
||||||
const GprsCodingScheme &cs);
|
const GprsCodingScheme &cs);
|
||||||
|
static int rlc_parse_ul_data_header_egprs_type_1(
|
||||||
|
struct gprs_rlc_data_info *rlc,
|
||||||
|
const uint8_t *data,
|
||||||
|
const GprsCodingScheme &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,
|
||||||
|
|
|
@ -610,8 +610,9 @@ static void write_packet_uplink_ack_egprs(
|
||||||
struct gprs_rlcmac_ul_tbf *tbf, bool is_final)
|
struct gprs_rlcmac_ul_tbf *tbf, bool is_final)
|
||||||
{
|
{
|
||||||
bitvec_write_field(dest, wp, 0, 2); // fixed 00
|
bitvec_write_field(dest, wp, 0, 2); // fixed 00
|
||||||
bitvec_write_field(dest, wp, 2, 4); // CHANNEL_CODING_COMMAND: MCS-3
|
/* CHANNEL_CODING_COMMAND */
|
||||||
// bitvec_write_field(dest, wp, tbf->current_cs() - 1, 4); // CHANNEL_CODING_COMMAND
|
bitvec_write_field(dest, wp,
|
||||||
|
tbf->current_cs().to_num() - 1, 4);
|
||||||
bitvec_write_field(dest, wp, 0, 1); // 0: no RESEGMENT (nyi)
|
bitvec_write_field(dest, wp, 0, 1); // 0: no RESEGMENT (nyi)
|
||||||
bitvec_write_field(dest, wp, 1, 1); // PRE_EMPTIVE_TRANSMISSION, TODO: This resembles GPRS, change it?
|
bitvec_write_field(dest, wp, 1, 1); // PRE_EMPTIVE_TRANSMISSION, TODO: This resembles GPRS, change it?
|
||||||
bitvec_write_field(dest, wp, 0, 1); // 0: no PRR_RETRANSMISSION_REQUEST, TODO: clarify
|
bitvec_write_field(dest, wp, 0, 1); // 0: no PRR_RETRANSMISSION_REQUEST, TODO: clarify
|
||||||
|
|
|
@ -632,8 +632,8 @@ void GprsMs::update_cs_ul(const pcu_l1_meas *meas)
|
||||||
high = bts_data->cs_lqual_ranges[current_cs_num-1].high;
|
high = bts_data->cs_lqual_ranges[current_cs_num-1].high;
|
||||||
} else if (m_current_cs_ul.isEgprs()) {
|
} else if (m_current_cs_ul.isEgprs()) {
|
||||||
/* TODO, use separate table */
|
/* TODO, use separate table */
|
||||||
if (current_cs_num > 4)
|
if (current_cs_num > MAX_GPRS_CS)
|
||||||
current_cs_num = 4;
|
current_cs_num = MAX_GPRS_CS;
|
||||||
low = bts_data->cs_lqual_ranges[current_cs_num-1].low;
|
low = bts_data->cs_lqual_ranges[current_cs_num-1].low;
|
||||||
high = bts_data->cs_lqual_ranges[current_cs_num-1].high;
|
high = bts_data->cs_lqual_ranges[current_cs_num-1].high;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -189,8 +189,8 @@ int main(int argc, char *argv[])
|
||||||
bts->cs_adj_lower_limit = 10; /* Increase CS if the error rate is below */
|
bts->cs_adj_lower_limit = 10; /* Increase CS if the error rate is below */
|
||||||
bts->max_cs_ul = 4;
|
bts->max_cs_ul = 4;
|
||||||
bts->max_cs_dl = 4;
|
bts->max_cs_dl = 4;
|
||||||
bts->max_mcs_ul = 4;
|
bts->max_mcs_ul = MAX_GPRS_CS;
|
||||||
bts->max_mcs_dl = 4;
|
bts->max_mcs_dl = MAX_GPRS_CS;
|
||||||
/* CS-1 to CS-4 */
|
/* CS-1 to CS-4 */
|
||||||
bts->cs_lqual_ranges[0].low = -256;
|
bts->cs_lqual_ranges[0].low = -256;
|
||||||
bts->cs_lqual_ranges[0].high = 6;
|
bts->cs_lqual_ranges[0].high = 6;
|
||||||
|
|
Loading…
Reference in New Issue