aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-06-04 12:12:32 +0200
committerJacob Erlbeck <jerlbeck@sysmocom.de>2015-06-04 19:25:21 +0200
commitff181e90e9e26fa53ba5fff74848701f91ac0236 (patch)
treeffc09bd30cf7f0b02a5ad27f20992ea0326b0186
parent8c15e1561e456930ece94b2844adc06311e14f9f (diff)
tbf: Automagically adjust CS (TODO)
TODO: - commit message - doesn't really update the CS yet - handles the DL only yet
-rw-r--r--src/bts.h3
-rw-r--r--src/pcu_main.cpp3
-rw-r--r--src/rlc.h2
-rw-r--r--src/tbf.h1
-rw-r--r--src/tbf_dl.cpp63
5 files changed, 72 insertions, 0 deletions
diff --git a/src/bts.h b/src/bts.h
index af66dfc8..b31db5fc 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -142,6 +142,9 @@ struct gprs_rlcmac_bts {
uint8_t alpha, gamma;
uint32_t dl_tbf_idle_msec; /* hold time for idle DL TBFs */
uint32_t ms_idle_sec;
+ uint8_t cs_adj_enabled;
+ uint8_t cs_adj_upper_limit;
+ uint8_t cs_adj_lower_limit;
/* TBF handling, make private or move into TBFController */
/* list of uplink TBFs */
diff --git a/src/pcu_main.cpp b/src/pcu_main.cpp
index 9e96af08..2e4a970f 100644
--- a/src/pcu_main.cpp
+++ b/src/pcu_main.cpp
@@ -173,6 +173,9 @@ int main(int argc, char *argv[])
bts->n3105 = 8;
bts->alpha = 0; /* a = 0.0 */
bts->ms_idle_sec = 60; /* slightly above T3314 (default 44s, 24.008, 11.2.2) */
+ bts->cs_adj_enabled = 1;
+ bts->cs_adj_upper_limit = 33; /* Decrease CS if the error rate is above */
+ bts->cs_adj_lower_limit = 10; /* Increase CS if the error rate is below */
msgb_set_talloc_ctx(tall_pcu_ctx);
diff --git a/src/rlc.h b/src/rlc.h
index 55cae3ff..313f3c72 100644
--- a/src/rlc.h
+++ b/src/rlc.h
@@ -59,6 +59,8 @@ struct gprs_rlc_data {
uint8_t block[RLC_MAX_LEN];
/* block len of history */
uint8_t len;
+
+ uint8_t cs;
};
/*
diff --git a/src/tbf.h b/src/tbf.h
index f50c489a..8e4c3b98 100644
--- a/src/tbf.h
+++ b/src/tbf.h
@@ -363,6 +363,7 @@ protected:
bool dl_window_stalled() const;
void reuse_tbf(const uint8_t *data, const uint16_t len);
void start_llc_timer();
+ int analyse_errors(char *show_rbb, uint8_t ssn);
struct osmo_timer_list m_llc_timer;
};
diff --git a/src/tbf_dl.cpp b/src/tbf_dl.cpp
index 405f5e6a..38b09c43 100644
--- a/src/tbf_dl.cpp
+++ b/src/tbf_dl.cpp
@@ -412,6 +412,7 @@ struct msgb *gprs_rlcmac_dl_tbf::create_new_bsn(const uint32_t fn, const uint8_t
/* now we still have untransmitted LLC data, so we fill mac block */
rlc_data = m_rlc.block(bsn);
data = rlc_data->prepare(block_data_len);
+ rlc_data->cs = cs;
rh = (struct rlc_dl_header *)data;
rh->pt = 0; /* Data Block */
@@ -669,6 +670,48 @@ struct msgb *gprs_rlcmac_dl_tbf::create_dl_acked_block(
return dl_msg;
}
+static uint16_t bitnum_to_bsn(int bitnum, uint16_t ssn, uint16_t mod_sns)
+{
+ return (ssn - 1 - bitnum) & mod_sns;
+}
+
+int gprs_rlcmac_dl_tbf::analyse_errors(char *show_rbb, uint8_t ssn)
+{
+ gprs_rlc_data *rlc_data;
+ uint16_t lost = 0, received = 0;
+
+ /* SSN - 1 is in range V(A)..V(S)-1 */
+ for (int bitpos = 0; bitpos < m_window.ws(); bitpos++) {
+ uint16_t bsn = bitnum_to_bsn(bitpos, ssn, m_window.mod_sns());
+
+ if (bsn == ((m_window.v_a() - 1) & m_window.mod_sns()))
+ break;
+
+ rlc_data = m_rlc.block(bsn);
+ if (!rlc_data)
+ continue;
+
+ if (!rlc_data->cs > current_cs())
+ /* This block has already been encoded with a higher
+ * CS, so it doesn't help us to decide, whether the
+ * current CS is ok. Ignore it. */
+ continue;
+
+ if (show_rbb[m_window.ws() - 1 - bitpos] == 'R') {
+ if (!m_window.m_v_b.is_acked(bsn))
+ received += 1;
+ } else {
+ lost += 1;
+ }
+ }
+
+ if (lost + received == 0)
+ return -1;
+
+ return lost * 100 / (lost + received);
+}
+
+
int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
{
int16_t dist; /* must be signed */
@@ -676,6 +719,7 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
char show_rbb[65];
char show_v_b[RLC_MAX_SNS + 1];
const uint16_t mod_sns = m_window.mod_sns();
+ int error_rate;
Decoding::extract_rbb(rbb, show_rbb);
/* show received array in debug (bit 64..1) */
@@ -698,6 +742,25 @@ int gprs_rlcmac_dl_tbf::update_window(const uint8_t ssn, const uint8_t *rbb)
return 1; /* indicate to free TBF */
}
+ if (bts_data()->cs_adj_enabled) {
+ error_rate = analyse_errors(show_rbb, ssn);
+ if (error_rate >= 0) {
+ if (error_rate > bts_data()->cs_adj_upper_limit) {
+ LOGP(DRLCMACDL, LOGL_INFO,
+ "%s High error rate %d%%, would reduce CS level\n",
+ name(), error_rate);
+ } else if (error_rate < bts_data()->cs_adj_lower_limit) {
+ LOGP(DRLCMACDL, LOGL_INFO,
+ "%s Low error rate %d%%, would increase CS level\n",
+ name(), error_rate);
+ } else {
+ LOGP(DRLCMACDL, LOGL_DEBUG,
+ "%s Medium error rate %d%%, ignored\n",
+ name(), error_rate);
+ }
+ }
+ }
+
m_window.update(bts, show_rbb, ssn,
&lost, &received);