aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-06-04 17:46:33 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2015-06-08 09:40:48 +0200
commit8158ea7288f57d7bc66d8ccd1c278999fd656076 (patch)
treeb6e7a15d91b48afc2ac7559d1a27ebab33cb4ee1
parent144a1d0516187d09f80c8b9125c6e51b4988503f (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
-rw-r--r--src/gprs_ms.cpp36
-rw-r--r--src/gprs_ms.h2
2 files changed, 32 insertions, 6 deletions
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp
index f5924fd..c8d598e 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;
}
}
diff --git a/src/gprs_ms.h b/src/gprs_ms.h
index 27c4be4..90b81fe 100644
--- a/src/gprs_ms.h
+++ b/src/gprs_ms.h
@@ -130,6 +130,8 @@ private:
LListHead<GprsMs> m_list;
struct osmo_timer_list m_timer;
unsigned m_delay;
+
+ int64_t m_last_cs_not_low;
};
inline uint32_t GprsMs::tlli() const