From 898dddb1d122068700694b59b9261fe07fa9cdef Mon Sep 17 00:00:00 2001 From: Max Date: Tue, 12 Mar 2019 15:50:57 +0100 Subject: MCS: add Channel Coding Command encoder Add function to encode MCS value as proper EDGE or GPRS Channel Coding value according to 3GPP TS 44.060 and corresponding helpers. Use it for everything except IA Rest Octet encoding which is done in a follow-up patches to make sure that we distinguish between encoding-related changes to test output and unrelated changes. Change-Id: I127fb29f5aaf77a7f6c4c565dfeb3b711af9845d --- src/coding_scheme.c | 13 +++++++++++++ src/coding_scheme.h | 2 ++ src/gprs_coding_scheme.cpp | 5 +---- src/gprs_coding_scheme.h | 1 + src/gprs_ms.cpp | 22 ++++++++++------------ tests/ms/MsTest.cpp | 4 ++-- tests/tbf/TbfTest.cpp | 4 ++-- 7 files changed, 31 insertions(+), 20 deletions(-) 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 { \ -- cgit v1.2.3