aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/bts.cpp113
-rw-r--r--src/bts.h19
-rw-r--r--src/gprs_bssgp_pcu.cpp8
-rw-r--r--src/gprs_ms.cpp35
-rw-r--r--src/pcu_l1_if.cpp2
-rw-r--r--src/pcu_vty.c46
6 files changed, 168 insertions, 55 deletions
diff --git a/src/bts.cpp b/src/bts.cpp
index 359f2d59..c2e3b9c9 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -219,10 +219,10 @@ static void bts_init(struct gprs_rlcmac_bts *bts, BTS* bts_obj)
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 */
- bts->max_cs_ul = MAX_GPRS_CS;
- bts->max_cs_dl = MAX_GPRS_CS;
- bts->max_mcs_ul = MAX_EDGE_MCS;
- bts->max_mcs_dl = MAX_EDGE_MCS;
+ bts->vty.max_cs_ul = MAX_GPRS_CS;
+ bts->vty.max_cs_dl = MAX_GPRS_CS;
+ bts->vty.max_mcs_ul = MAX_EDGE_MCS;
+ bts->vty.max_mcs_dl = MAX_EDGE_MCS;
/* CS-1 to CS-4 */
bts->cs_lqual_ranges[0].low = -256;
bts->cs_lqual_ranges[0].high = 6;
@@ -320,6 +320,10 @@ struct rate_ctr_group *bts_main_data_stats()
BTS::BTS()
: m_cur_fn(0)
, m_cur_blk_fn(-1)
+ , m_max_cs_dl(MAX_GPRS_CS)
+ , m_max_cs_ul(MAX_GPRS_CS)
+ , m_max_mcs_dl(MAX_EDGE_MCS)
+ , m_max_mcs_ul(MAX_EDGE_MCS)
, m_pollController(*this)
, m_sba(*this)
, m_ms_store(this)
@@ -1072,6 +1076,53 @@ void BTS::snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup)
bitvec_free(immediate_assignment);
}
+/* return maximum DL CS supported by BTS and allowed by VTY */
+uint8_t BTS::max_cs_dl(void) const
+{
+ return m_max_cs_dl;
+}
+
+/* return maximum UL CS supported by BTS and allowed by VTY */
+uint8_t BTS::max_cs_ul(void) const
+{
+ return m_max_cs_ul;
+}
+
+/* return maximum DL MCS supported by BTS and allowed by VTY */
+uint8_t BTS::max_mcs_dl(void) const
+{
+ return m_max_mcs_dl;
+}
+
+/* return maximum UL MCS supported by BTS and allowed by VTY */
+uint8_t BTS::max_mcs_ul(void) const
+{
+ return m_max_mcs_ul;
+}
+
+/* Set maximum DL CS supported by BTS and allowed by VTY */
+void BTS::set_max_cs_dl(uint8_t cs_dl)
+{
+ m_max_cs_dl = cs_dl;
+}
+
+/* Set maximum UL CS supported by BTS and allowed by VTY */
+void BTS::set_max_cs_ul(uint8_t cs_ul)
+{
+ m_max_cs_ul = cs_ul;
+}
+
+/* Set maximum DL MCS supported by BTS and allowed by VTY */
+void BTS::set_max_mcs_dl(uint8_t mcs_dl)
+{
+ m_max_mcs_dl = mcs_dl;
+}
+
+/* Set maximum UL MCS supported by BTS and allowed by VTY */
+void BTS::set_max_mcs_ul(uint8_t mcs_ul)
+{
+ m_max_mcs_ul = mcs_ul;
+}
GprsMs *BTS::ms_alloc(uint8_t ms_class, uint8_t egprs_ms_class)
{
@@ -1161,3 +1212,57 @@ void gprs_rlcmac_trx::unreserve_slots(enum gprs_rlcmac_tbf_direction dir,
if (slots & (1 << i))
pdch[i].unreserve(dir);
}
+
+void bts_set_max_cs(struct gprs_rlcmac_bts *bts, uint8_t cs_dl, uint8_t cs_ul)
+{
+ int i;
+
+ bts->vty.max_cs_dl = cs_dl;
+ cs_dl = 0;
+ for (i = bts->vty.max_cs_dl - 1; i >= 0; i--) {
+ if (bts->cs_mask & (1 << i)) {
+ cs_dl = i + 1;
+ break;
+ }
+ }
+
+ bts->vty.max_cs_ul = cs_ul;
+ cs_ul = 0;
+ for (i = bts->vty.max_cs_ul - 1; i >= 0; i--) {
+ if (bts->cs_mask & (1 << i)) {
+ cs_ul = i + 1;
+ break;
+ }
+ }
+
+ LOGP(DRLCMAC, LOGL_DEBUG, "New max CS: DL=%u UL=%u\n", cs_dl, cs_ul);
+ bts->bts->set_max_cs_dl(cs_dl);
+ bts->bts->set_max_cs_ul(cs_ul);
+}
+
+void bts_set_max_mcs(struct gprs_rlcmac_bts *bts, uint8_t mcs_dl, uint8_t mcs_ul)
+{
+ int i;
+
+ bts->vty.max_mcs_dl = mcs_dl;
+ mcs_dl = 0;
+ for (i = bts->vty.max_mcs_dl - 1; i >= 0; i--) {
+ if (bts->mcs_mask & (1 << i)) {
+ mcs_dl = i + 1;
+ break;
+ }
+ }
+
+ bts->vty.max_mcs_ul = mcs_ul;
+ mcs_ul = 0;
+ for (i = bts->vty.max_mcs_ul - 1; i >= 0; i--) {
+ if (bts->mcs_mask & (1 << i)) {
+ mcs_ul = i + 1;
+ break;
+ }
+ }
+
+ LOGP(DRLCMAC, LOGL_DEBUG, "New max MCS: DL=%u UL=%u\n", mcs_dl, mcs_ul);
+ bts->bts->set_max_mcs_dl(mcs_dl);
+ bts->bts->set_max_mcs_ul(mcs_ul);
+}
diff --git a/src/bts.h b/src/bts.h
index 73354838..8d7f6caf 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -114,8 +114,10 @@ struct gprs_rlcmac_bts {
uint16_t mcs_mask; /* Allowed MCS mask from BTS */
uint8_t initial_cs_dl, initial_cs_ul;
uint8_t initial_mcs_dl, initial_mcs_ul;
- uint8_t max_cs_dl, max_cs_ul;
- uint8_t max_mcs_dl, max_mcs_ul;
+ struct { /* Config Values set by VTY */
+ uint8_t max_cs_dl, max_cs_ul;
+ uint8_t max_mcs_dl, max_mcs_ul;
+ } vty;
uint8_t force_cs; /* 0=use from BTS 1=use from VTY */
uint16_t force_llc_lifetime; /* overrides lifetime from SGSN */
uint32_t llc_discard_csec;
@@ -329,6 +331,15 @@ public:
void snd_dl_ass(gprs_rlcmac_tbf *tbf, bool poll, uint16_t pgroup);
+ uint8_t max_cs_dl(void) const;
+ uint8_t max_cs_ul(void) const;
+ uint8_t max_mcs_dl(void) const;
+ uint8_t max_mcs_ul(void) const;
+ void set_max_cs_dl(uint8_t cs_dl);
+ void set_max_cs_ul(uint8_t cs_ul);
+ void set_max_mcs_dl(uint8_t mcs_dl);
+ void set_max_mcs_ul(uint8_t mcs_ul);
+
GprsMsStorage &ms_store();
GprsMs *ms_by_tlli(uint32_t tlli, uint32_t old_tlli = 0);
GprsMs *ms_by_imsi(const char *imsi);
@@ -358,6 +369,8 @@ private:
int m_cur_fn;
int m_cur_blk_fn;
struct gprs_rlcmac_bts m_bts;
+ uint8_t m_max_cs_dl, m_max_cs_ul;
+ uint8_t m_max_mcs_dl, m_max_mcs_ul;
PollController m_pollController;
SBAController m_sba;
struct rate_ctr_group *m_ratectrs;
@@ -442,6 +455,8 @@ extern "C" {
struct gprs_rlcmac_bts *bts_main_data();
struct rate_ctr_group *bts_main_data_stats();
struct osmo_stat_item_group *bts_main_data_stat_items();
+ void bts_set_max_cs(struct gprs_rlcmac_bts *bts, uint8_t cs_dl, uint8_t cs_ul);
+ void bts_set_max_mcs(struct gprs_rlcmac_bts *bts, uint8_t mcs_dl, uint8_t mcs_ul);
#ifdef __cplusplus
}
diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp
index 4b5582d3..f87681c3 100644
--- a/src/gprs_bssgp_pcu.cpp
+++ b/src/gprs_bssgp_pcu.cpp
@@ -753,8 +753,8 @@ static enum CodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts)
}
}
}
- } else if (bts->max_mcs_dl) {
- num = bts->max_mcs_dl;
+ } else if (bts->bts->max_mcs_dl()) {
+ num = bts->bts->max_mcs_dl();
} else {
num = 9;
}
@@ -774,8 +774,8 @@ static enum CodingScheme max_coding_scheme_dl(struct gprs_rlcmac_bts *bts)
}
}
}
- } else if (bts->max_cs_dl) {
- num = bts->max_cs_dl;
+ } else if (bts->bts->max_cs_dl()) {
+ num = bts->bts->max_cs_dl();
}
if (!num)
diff --git a/src/gprs_ms.cpp b/src/gprs_ms.cpp
index 9576c0d7..b2956869 100644
--- a/src/gprs_ms.cpp
+++ b/src/gprs_ms.cpp
@@ -541,9 +541,8 @@ void GprsMs::set_egprs_ms_class(uint8_t ms_class_)
m_egprs_ms_class = ms_class_;
- const struct gprs_rlcmac_bts *bts = m_bts->bts_data();
- if (mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts->max_mcs_ul)) &&
- mcs_is_edge_gmsk(mcs_get_egprs_by_num(bts->max_mcs_dl)) &&
+ if (mcs_is_edge_gmsk(mcs_get_egprs_by_num(m_bts->max_mcs_ul())) &&
+ mcs_is_edge_gmsk(mcs_get_egprs_by_num(m_bts->max_mcs_dl())) &&
mode() != EGPRS)
{
set_mode(EGPRS_GMSK);
@@ -609,26 +608,23 @@ void GprsMs::update_error_rate(gprs_rlcmac_tbf *tbf, int error_rate)
enum CodingScheme GprsMs::max_cs_ul() const
{
- struct gprs_rlcmac_bts *bts_data;
-
OSMO_ASSERT(m_bts != NULL);
- bts_data = m_bts->bts_data();
if (mcs_is_gprs(m_current_cs_ul)) {
- if (!bts_data->max_cs_ul) {
+ if (!m_bts->max_cs_ul()) {
return CS4;
}
- return mcs_get_gprs_by_num(bts_data->max_cs_ul);
+ return mcs_get_gprs_by_num(m_bts->max_cs_ul());
}
if (!mcs_is_edge(m_current_cs_ul))
return UNKNOWN;
- if (bts_data->max_mcs_ul)
- return mcs_get_egprs_by_num(bts_data->max_mcs_ul);
- else if (bts_data->max_cs_ul)
- return mcs_get_gprs_by_num(bts_data->max_cs_ul);
+ if (m_bts->max_mcs_ul())
+ return mcs_get_egprs_by_num(m_bts->max_mcs_ul());
+ else if (m_bts->max_cs_ul())
+ return mcs_get_gprs_by_num(m_bts->max_cs_ul());
return MCS4;
}
@@ -640,26 +636,23 @@ void GprsMs::set_current_cs_dl(enum CodingScheme scheme)
enum CodingScheme GprsMs::max_cs_dl() const
{
- struct gprs_rlcmac_bts *bts_data;
-
OSMO_ASSERT(m_bts != NULL);
- bts_data = m_bts->bts_data();
if (mcs_is_gprs(m_current_cs_dl)) {
- if (!bts_data->max_cs_dl) {
+ if (!m_bts->max_cs_dl()) {
return CS4;
}
- return mcs_get_gprs_by_num(bts_data->max_cs_dl);
+ return mcs_get_gprs_by_num(m_bts->max_cs_dl());
}
if (!mcs_is_edge(m_current_cs_dl))
return UNKNOWN;
- if (bts_data->max_mcs_dl)
- return mcs_get_egprs_by_num(bts_data->max_mcs_dl);
- else if (bts_data->max_cs_dl)
- return mcs_get_gprs_by_num(bts_data->max_cs_dl);
+ if (m_bts->max_mcs_dl())
+ return mcs_get_egprs_by_num(m_bts->max_mcs_dl());
+ else if (m_bts->max_cs_dl())
+ return mcs_get_gprs_by_num(m_bts->max_cs_dl());
return MCS4;
}
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index 7e517634..4f96567c 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -621,6 +621,7 @@ bssgp_failed:
if (allowed)
LOGP(DL1IF, LOGL_DEBUG, " Use CS%d\n", i + 1);
}
+ bts_set_max_cs(bts, bts->vty.max_cs_dl, bts->vty.max_cs_ul); /* recalc max CS values */
bts->mcs_mask = 0;
for (i = 0; i < 9; i++) {
@@ -629,6 +630,7 @@ bssgp_failed:
if (allowed)
LOGP(DL1IF, LOGL_DEBUG, " Use MCS%d\n", i + 1);
}
+ bts_set_max_mcs(bts, bts->vty.max_mcs_dl, bts->vty.max_mcs_ul); /* recalc max MCS values */
LOGP(DL1IF, LOGL_DEBUG, " initial_cs=%d\n", info_ind->initial_cs);
LOGP(DL1IF, LOGL_DEBUG, " initial_mcs=%d\n", info_ind->initial_mcs);
diff --git a/src/pcu_vty.c b/src/pcu_vty.c
index 6dfcdf54..bd835446 100644
--- a/src/pcu_vty.c
+++ b/src/pcu_vty.c
@@ -133,13 +133,13 @@ static int config_write_pcu(struct vty *vty)
vty_out(vty, " cs %d %d%s", bts->initial_cs_dl,
bts->initial_cs_ul, VTY_NEWLINE);
}
- if (bts->max_cs_dl && bts->max_cs_ul) {
- if (bts->max_cs_ul == bts->max_cs_dl)
- vty_out(vty, " cs max %d%s", bts->max_cs_dl,
+ if (bts->vty.max_cs_dl && bts->vty.max_cs_ul) {
+ if (bts->vty.max_cs_ul == bts->vty.max_cs_dl)
+ vty_out(vty, " cs max %d%s", bts->vty.max_cs_dl,
VTY_NEWLINE);
else
- vty_out(vty, " cs max %d %d%s", bts->max_cs_dl,
- bts->max_cs_ul, VTY_NEWLINE);
+ vty_out(vty, " cs max %d %d%s", bts->vty.max_cs_dl,
+ bts->vty.max_cs_ul, VTY_NEWLINE);
}
if (bts->cs_adj_enabled)
vty_out(vty, " cs threshold %d %d%s",
@@ -191,13 +191,13 @@ static int config_write_pcu(struct vty *vty)
bts->initial_mcs_ul, VTY_NEWLINE);
}
- if (bts->max_mcs_dl && bts->max_mcs_ul) {
- if (bts->max_mcs_ul == bts->max_mcs_dl)
- vty_out(vty, " mcs max %d%s", bts->max_mcs_dl,
+ if (bts->vty.max_mcs_dl && bts->vty.max_mcs_ul) {
+ if (bts->vty.max_mcs_ul == bts->vty.max_mcs_dl)
+ vty_out(vty, " mcs max %d%s", bts->vty.max_mcs_dl,
VTY_NEWLINE);
else
- vty_out(vty, " mcs max %d %d%s", bts->max_mcs_dl,
- bts->max_mcs_ul, VTY_NEWLINE);
+ vty_out(vty, " mcs max %d %d%s", bts->vty.max_mcs_dl,
+ bts->vty.max_mcs_ul, VTY_NEWLINE);
}
vty_out(vty, " window-size %d %d%s", bts->ws_base, bts->ws_pdch,
@@ -494,14 +494,15 @@ DEFUN_ATTR(cfg_pcu_cs_max,
CMD_ATTR_IMMEDIATE)
{
struct gprs_rlcmac_bts *bts = bts_main_data();
- uint8_t cs = atoi(argv[0]);
+ uint8_t cs_dl = atoi(argv[0]);
+ uint8_t cs_ul;
- bts->max_cs_dl = cs;
if (argc > 1)
- bts->max_cs_ul = atoi(argv[1]);
+ cs_ul = atoi(argv[1]);
else
- bts->max_cs_ul = cs;
+ cs_ul = cs_dl;
+ bts_set_max_cs(bts, cs_dl, cs_ul);
return CMD_SUCCESS;
}
@@ -513,9 +514,7 @@ DEFUN_ATTR(cfg_pcu_no_cs_max,
{
struct gprs_rlcmac_bts *bts = bts_main_data();
- bts->max_cs_dl = 0;
- bts->max_cs_ul = 0;
-
+ bts_set_max_cs(bts, 0, 0);
return CMD_SUCCESS;
}
@@ -564,14 +563,15 @@ DEFUN_ATTR(cfg_pcu_mcs_max,
CMD_ATTR_IMMEDIATE)
{
struct gprs_rlcmac_bts *bts = bts_main_data();
- uint8_t mcs = atoi(argv[0]);
+ uint8_t mcs_dl = atoi(argv[0]);
+ uint8_t mcs_ul;
- bts->max_mcs_dl = mcs;
if (argc > 1)
- bts->max_mcs_ul = atoi(argv[1]);
+ mcs_ul = atoi(argv[1]);
else
- bts->max_mcs_ul = mcs;
+ mcs_ul = mcs_dl;
+ bts_set_max_mcs(bts, mcs_dl, mcs_ul);
return CMD_SUCCESS;
}
@@ -583,9 +583,7 @@ DEFUN_ATTR(cfg_pcu_no_mcs_max,
{
struct gprs_rlcmac_bts *bts = bts_main_data();
- bts->max_mcs_dl = 0;
- bts->max_mcs_ul = 0;
-
+ bts_set_max_mcs(bts, 0, 0);
return CMD_SUCCESS;
}