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
This commit is contained in:
Jacob Erlbeck 2015-06-04 17:46:33 +02:00
parent 144a1d0516
commit 8158ea7288
2 changed files with 32 additions and 6 deletions

View File

@ -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;
}
}

View File

@ -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