diff --git a/src/coding_scheme.c b/src/coding_scheme.c index 4a5d0d4d..a4ae8827 100644 --- a/src/coding_scheme.c +++ b/src/coding_scheme.c @@ -64,6 +64,19 @@ bool mcs_is_edge_gmsk(enum CodingScheme cs) return false; } +/* Return 3GPP TS 44.060 ยง12.10d (EDGE) or Table 11.2.28.2 (GPRS) Channel Coding Command value */ +uint8_t mcs_chan_code(enum CodingScheme cs) +{ + if (mcs_is_gprs(cs)) + return cs - CS1; + + if (mcs_is_edge(cs)) + return cs - MCS1; + + /* Defaults to (M)CS1 */ + return 0; +} + static struct { struct { uint8_t data_header_bits; diff --git a/src/coding_scheme.h b/src/coding_scheme.h index 3a9ef250..aac4bba1 100644 --- a/src/coding_scheme.h +++ b/src/coding_scheme.h @@ -37,6 +37,8 @@ bool mcs_is_gprs(enum CodingScheme cs); bool mcs_is_edge(enum CodingScheme cs); bool mcs_is_edge_gmsk(enum CodingScheme cs); +uint8_t mcs_chan_code(enum CodingScheme cs); + enum HeaderType { HEADER_INVALID, HEADER_GPRS_CONTROL, diff --git a/src/gprs_coding_scheme.cpp b/src/gprs_coding_scheme.cpp index 8e6593b9..a149f814 100644 --- a/src/gprs_coding_scheme.cpp +++ b/src/gprs_coding_scheme.cpp @@ -67,10 +67,7 @@ CodingScheme GprsCodingScheme::get_retx_mcs(const GprsCodingScheme mcs, const GprsCodingScheme demanded_mcs, const unsigned arq_type) { - OSMO_ASSERT(mcs.to_num() > 0); - OSMO_ASSERT(demanded_mcs.to_num() > 0); - - return egprs_mcs_retx_tbl[arq_type][mcs.to_num() - 1][demanded_mcs.to_num() - 1]; + return egprs_mcs_retx_tbl[arq_type][mcs_chan_code(mcs)][mcs_chan_code(demanded_mcs)]; } static struct { diff --git a/src/gprs_coding_scheme.h b/src/gprs_coding_scheme.h index 728ffd66..d5604fb4 100644 --- a/src/gprs_coding_scheme.h +++ b/src/gprs_coding_scheme.h @@ -82,6 +82,7 @@ private: 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)) diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index f8f6227a..19f2ecb2 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -523,7 +523,7 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate) m_nack_rate_dl = error_rate; if (error_rate > bts_data->cs_adj_upper_limit) { - if (m_current_cs_dl.to_num() > 1) { + if (mcs_chan_code(m_current_cs_dl) > 0) { m_current_cs_dl.dec(mode()); LOGP(DRLCMACDL, LOGL_INFO, "MS (IMSI %s): High error rate %d%%, " @@ -621,7 +621,7 @@ void GprsMs::update_cs_ul(const pcu_l1_meas *meas) int low; int high; GprsCodingScheme new_cs_ul = m_current_cs_ul; - uint8_t current_cs_num = m_current_cs_ul.to_num(); + uint8_t current_cs = mcs_chan_code(m_current_cs_ul); bts_data = m_bts->bts_data(); @@ -632,8 +632,6 @@ void GprsMs::update_cs_ul(const pcu_l1_meas *meas) return; } - OSMO_ASSERT(current_cs_num > 0); - if (!m_current_cs_ul) { LOGP(DRLCMACMEAS, LOGL_ERROR, "Unable to update UL (M)CS because it's not set: %s\n", @@ -651,15 +649,15 @@ void GprsMs::update_cs_ul(const pcu_l1_meas *meas) old_link_qual = meas->link_qual; if (mcs_is_gprs(m_current_cs_ul)) { - if (current_cs_num > MAX_GPRS_CS) - current_cs_num = MAX_GPRS_CS; - low = bts_data->cs_lqual_ranges[current_cs_num-1].low; - high = bts_data->cs_lqual_ranges[current_cs_num-1].high; + if (current_cs >= MAX_GPRS_CS) + current_cs = MAX_GPRS_CS - 1; + low = bts_data->cs_lqual_ranges[current_cs].low; + high = bts_data->cs_lqual_ranges[current_cs].high; } else if (mcs_is_edge(m_current_cs_ul)) { - if (current_cs_num > MAX_EDGE_MCS) - current_cs_num = MAX_EDGE_MCS; - low = bts_data->mcs_lqual_ranges[current_cs_num-1].low; - high = bts_data->mcs_lqual_ranges[current_cs_num-1].high; + if (current_cs >= MAX_EDGE_MCS) + current_cs = MAX_EDGE_MCS - 1; + low = bts_data->mcs_lqual_ranges[current_cs].low; + high = bts_data->mcs_lqual_ranges[current_cs].high; } else { LOGP(DRLCMACMEAS, LOGL_ERROR, "Unable to update UL (M)CS because it's neither GPRS nor EDGE: %s\n", diff --git a/tests/ms/MsTest.cpp b/tests/ms/MsTest.cpp index 2b0bc0ff..aa600e50 100644 --- a/tests/ms/MsTest.cpp +++ b/tests/ms/MsTest.cpp @@ -520,11 +520,11 @@ static void test_ms_cs_selection() dl_tbf->set_ms(ms); OSMO_ASSERT(!ms->is_idle()); - OSMO_ASSERT(ms->current_cs_dl().to_num() == 4); + OSMO_ASSERT(mcs_chan_code(ms->current_cs_dl()) == 3); bts->cs_downgrade_threshold = 200; - OSMO_ASSERT(ms->current_cs_dl().to_num() == 3); + OSMO_ASSERT(mcs_chan_code(ms->current_cs_dl()) == 2); talloc_free(dl_tbf); diff --git a/tests/tbf/TbfTest.cpp b/tests/tbf/TbfTest.cpp index 993ca10b..6dc802cf 100644 --- a/tests/tbf/TbfTest.cpp +++ b/tests/tbf/TbfTest.cpp @@ -2737,12 +2737,12 @@ static void tbf_cleanup(gprs_rlcmac_dl_tbf *dl_tbf) #define CHECK_UNACKED(tbf, cs, bsn) do { \ OSMO_ASSERT(tbf->window()->m_v_b.is_unacked(bsn)); \ - OSMO_ASSERT(tbf->m_rlc.block(bsn)->cs_current_trans.to_num() == cs); \ + OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \ } while(0) #define CHECK_NACKED(tbf, cs, bsn) do { \ OSMO_ASSERT(tbf->window()->m_v_b.is_nacked(bsn)); \ - OSMO_ASSERT(tbf->m_rlc.block(bsn)->cs_current_trans.to_num() == cs); \ + OSMO_ASSERT(mcs_chan_code(tbf->m_rlc.block(bsn)->cs_current_trans) == cs - 1); \ } while(0) #define MAKE_ACKED(m, tbf, fn, cs, check_unacked) do { \