aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2019-03-12 15:50:57 +0100
committerMax <msuraev@sysmocom.de>2019-03-27 12:32:04 +0000
commit898dddb1d122068700694b59b9261fe07fa9cdef (patch)
tree6035fb7f0eaa15f4c5dffcf51c4a4f5c9df31fc2
parent48b1e7a86f2923c9de466c4e30697b3d2b13072b (diff)
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
-rw-r--r--src/coding_scheme.c13
-rw-r--r--src/coding_scheme.h2
-rw-r--r--src/gprs_coding_scheme.cpp5
-rw-r--r--src/gprs_coding_scheme.h1
-rw-r--r--src/gprs_ms.cpp22
-rw-r--r--tests/ms/MsTest.cpp4
-rw-r--r--tests/tbf/TbfTest.cpp4
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 { \