From ebebf5d175e6e6311229c2d61914c575a6c001fd Mon Sep 17 00:00:00 2001 From: Aravind Sirsikar Date: Thu, 19 May 2016 21:19:40 +0530 Subject: 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 --- src/bts.h | 2 +- src/decoding.cpp | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/decoding.h | 4 ++++ src/encoding.cpp | 5 +++-- src/gprs_ms.cpp | 4 ++-- src/pcu_main.cpp | 4 ++-- 6 files changed, 73 insertions(+), 9 deletions(-) diff --git a/src/bts.h b/src/bts.h index c975304..031baef 100644 --- a/src/bts.h +++ b/src/bts.h @@ -188,7 +188,7 @@ struct gprs_rlcmac_bts { uint8_t cs_adj_enabled; uint8_t cs_adj_upper_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[9]; uint16_t cs_downgrade_threshold; /* downgrade if less packets left (DL) */ uint16_t ws_base; uint16_t ws_pdch; /* increase WS by this value per PDCH */ diff --git a/src/decoding.cpp b/src/decoding.cpp index 2fb2428..16564ab 100644 --- a/src/decoding.cpp +++ b/src/decoding.cpp @@ -356,8 +356,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); break; case GprsCodingScheme::HEADER_EGPRS_DATA_TYPE_1 : - /* TODO: Support both header type 1 */ - /* fall through */ + cur_bit = rlc_parse_ul_data_header_egprs_type_1(rlc, data, cs); + break; default: LOGP(DRLCMACDL, LOGL_ERROR, "Decoding of uplink %s data blocks not yet supported.\n", @@ -454,6 +454,65 @@ int Decoding::rlc_parse_ul_data_header_egprs_type_2( 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, const uint8_t *data, const GprsCodingScheme &cs) { diff --git a/src/decoding.h b/src/decoding.h index 8aaf36b..ce83bd0 100644 --- a/src/decoding.h +++ b/src/decoding.h @@ -51,6 +51,10 @@ public: struct gprs_rlc_data_info *rlc, const uint8_t *data, 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( struct gprs_rlc_data_info *rlc, const uint8_t *data, diff --git a/src/encoding.cpp b/src/encoding.cpp index 6c50abe..44a0a0d 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -610,8 +610,9 @@ static void write_packet_uplink_ack_egprs( struct gprs_rlcmac_ul_tbf *tbf, bool is_final) { bitvec_write_field(dest, wp, 0, 2); // fixed 00 - bitvec_write_field(dest, wp, 2, 4); // CHANNEL_CODING_COMMAND: MCS-3 - // bitvec_write_field(dest, wp, tbf->current_cs() - 1, 4); // CHANNEL_CODING_COMMAND + /* 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, 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 diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index b9a04fb..8b0c8c4 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -637,8 +637,8 @@ void GprsMs::update_cs_ul(const pcu_l1_meas *meas) high = bts_data->cs_lqual_ranges[current_cs_num-1].high; } else if (m_current_cs_ul.isEgprs()) { /* TODO, use separate table */ - if (current_cs_num > 4) - current_cs_num = 4; + if (current_cs_num > 9) + current_cs_num = 9; low = bts_data->cs_lqual_ranges[current_cs_num-1].low; high = bts_data->cs_lqual_ranges[current_cs_num-1].high; } else { diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp index f66c631..82e1005 100644 --- a/src/pcu_main.cpp +++ b/src/pcu_main.cpp @@ -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->max_cs_ul = 4; bts->max_cs_dl = 4; - bts->max_mcs_ul = 4; - bts->max_mcs_dl = 4; + bts->max_mcs_ul = 9; + bts->max_mcs_dl = 9; /* CS-1 to CS-4 */ bts->cs_lqual_ranges[0].low = -256; bts->cs_lqual_ranges[0].high = 6; -- cgit v1.2.3