diff options
author | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-06-04 17:46:33 +0200 |
---|---|---|
committer | Jacob Erlbeck <jerlbeck@sysmocom.de> | 2015-06-08 09:40:48 +0200 |
commit | 8158ea7288f57d7bc66d8ccd1c278999fd656076 (patch) | |
tree | b6e7a15d91b48afc2ac7559d1a27ebab33cb4ee1 /src/gprs_ms.cpp | |
parent | 144a1d0516187d09f80c8b9125c6e51b4988503f (diff) |
ms: Add blocking period for CS upgrade
Currently the CS level is immediately increased if the error rate
drops below the lower threshold. Since the measurement values are not
damped, this behaviour leads to a quick return to higher CS values
even under bad radio conditions. Since with GPRS RLC/MAC blocks
cannot be resent with another coding scheme, increasing the CS value
should be done carefully.
This commit adds a blocking period that only allows higher CS values
if all error rate measurements were below the LOW threshold for a
certain amount of time (currently fixed to 1s).
Ticket: #1674
Sponsored-by: On-Waves ehf
Diffstat (limited to 'src/gprs_ms.cpp')
-rw-r--r-- | src/gprs_ms.cpp | 36 |
1 files changed, 30 insertions, 6 deletions
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp index f5924fd8..c8d598ee 100644 --- a/src/gprs_ms.cpp +++ b/src/gprs_ms.cpp @@ -25,6 +25,8 @@ #include "tbf.h" #include "gprs_debug.h" +#include <time.h> + extern "C" { #include <osmocom/core/talloc.h> #include <osmocom/core/utils.h> @@ -32,6 +34,14 @@ extern "C" { extern void *tall_pcu_ctx; +static int64_t now_msec() +{ + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + + return int64_t(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000; +} + struct GprsMsDefaultCallback: public GprsMs::Callback { virtual void ms_idle(class GprsMs *ms) { delete ms; @@ -96,6 +106,7 @@ GprsMs::GprsMs(BTS *bts, uint32_t tlli) : if (m_current_cs_dl < 1) m_current_cs_dl = 1; } + m_last_cs_not_low = now_msec(); } GprsMs::~GprsMs() @@ -354,6 +365,7 @@ void GprsMs::set_ms_class(uint8_t ms_class_) void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate) { struct gprs_rlcmac_bts *bts_data; + int64_t now; OSMO_ASSERT(m_bts != NULL); bts_data = m_bts->bts_data(); @@ -361,6 +373,8 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate) if (error_rate < 0) return; + now = now_msec(); + /* TODO: Support different CS values for UL and DL */ if (error_rate > bts_data->cs_adj_upper_limit) { @@ -371,19 +385,29 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate) "MS (IMSI %s): High error rate %d%%, " "reducing CS level to %d\n", imsi(), error_rate, m_current_cs_dl); + m_last_cs_not_low = now; } } else if (error_rate < bts_data->cs_adj_lower_limit) { if (m_current_cs_dl < 4) { - m_current_cs_dl += 1; - m_current_cs_ul = m_current_cs_dl; - LOGP(DRLCMACDL, LOGL_INFO, - "MS (IMSI %s): Low error rate %d%%, " - "increasing CS level to %d\n", - imsi(), error_rate, m_current_cs_dl); + if (now - m_last_cs_not_low > 1000) { + m_current_cs_dl += 1; + m_current_cs_ul = m_current_cs_dl; + LOGP(DRLCMACDL, LOGL_INFO, + "MS (IMSI %s): Low error rate %d%%, " + "increasing CS level to %d\n", + imsi(), error_rate, m_current_cs_dl); + m_last_cs_not_low = now; + } else { + LOGP(DRLCMACDL, LOGL_DEBUG, + "MS (IMSI %s): Low error rate %d%%, " + "ignored (within blocking period)\n", + imsi(), error_rate); + } } } else { LOGP(DRLCMACDL, LOGL_DEBUG, "MS (IMSI %s): Medium error rate %d%%, ignored\n", imsi(), error_rate); + m_last_cs_not_low = now; } } |