aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/bsc/handover_cfg.h19
-rw-r--r--include/osmocom/bsc/meas_rep.h6
-rw-r--r--src/osmo-bsc/handover_decision_2.c6
-rw-r--r--src/osmo-bsc/meas_rep.c19
-rw-r--r--tests/bsc/Makefile.am1
-rw-r--r--tests/handover_cfg.vty4
6 files changed, 33 insertions, 22 deletions
diff --git a/include/osmocom/bsc/handover_cfg.h b/include/osmocom/bsc/handover_cfg.h
index 6e003af94..551ce8df5 100644
--- a/include/osmocom/bsc/handover_cfg.h
+++ b/include/osmocom/bsc/handover_cfg.h
@@ -38,18 +38,6 @@ static inline int bool2i(bool arg)
return arg? 1 : 0;
}
-static inline bool a2tdma(const char *arg)
-{
- if (!strcmp(arg, "full"))
- return true;
- return false;
-}
-
-static inline const char *tdma2a(bool val)
-{
- return val? "full" : "subset";
-}
-
/* The HO_CFG_ONE_MEMBER macro gets redefined, depending on whether to define struct members,
* function declarations or definitions... It is of the format
* HO_CFG_ONE_MEMBER(TYPE, NAME, DEFAULT_VAL,
@@ -188,10 +176,13 @@ static inline const char *tdma2a(bool val)
"Disable in-call assignment\n" \
"Enable in-call assignment\n") \
\
- HO_CFG_ONE_MEMBER(bool, hodec2_full_tdma, subset, \
- "handover2 ", "tdma-measurement", "full|subset", a2tdma, "%s", tdma2a, \
+ HO_CFG_ONE_MEMBER(enum tdma_meas_set, hodec2_tdma_meas_set, subset, \
+ "handover2 ", "tdma-measurement", "auto|full|subset", \
+ tdma_meas_set_from_str, "%s", tdma_meas_set_name, \
HO_CFG_STR_HANDOVER2 \
"Define measurement set of TDMA frames\n" \
+ "Use full set when DTX is not in use, use subset when DTX is in use," \
+ " as indicated by each Measurement Report\n" \
"Full set of 102/104 TDMA frames\n" \
"Sub set of 4 TDMA frames (SACCH)\n") \
\
diff --git a/include/osmocom/bsc/meas_rep.h b/include/osmocom/bsc/meas_rep.h
index 5cfeb98fb..402a888b1 100644
--- a/include/osmocom/bsc/meas_rep.h
+++ b/include/osmocom/bsc/meas_rep.h
@@ -68,6 +68,12 @@ enum tdma_meas_set {
TDMA_MEAS_SET_AUTO,
};
+extern const struct value_string tdma_meas_set_names[];
+static inline const char *tdma_meas_set_name(enum tdma_meas_set val)
+{ return get_value_string(tdma_meas_set_names, val); }
+static inline enum tdma_meas_set tdma_meas_set_from_str(const char *name)
+{ return get_string_value(tdma_meas_set_names, name); }
+
/* obtain an average over the last 'num' fields in the meas reps */
int get_meas_rep_avg(const struct gsm_lchan *lchan,
enum tdma_meas_field field, enum tdma_meas_dir dir, enum tdma_meas_set set,
diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c
index 67208fe90..3fa1084e4 100644
--- a/src/osmo-bsc/handover_decision_2.c
+++ b/src/osmo-bsc/handover_decision_2.c
@@ -244,16 +244,14 @@ static struct gsm_meas_rep_cell *cell_in_rep(struct gsm_meas_rep *mr, uint16_t a
static int current_rxlev(struct gsm_lchan *lchan)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
- return get_meas_rep_avg(lchan, TDMA_MEAS_FIELD_RXLEV, TDMA_MEAS_DIR_DL,
- ho_get_hodec2_full_tdma(bts->ho) ? TDMA_MEAS_SET_FULL : TDMA_MEAS_SET_SUB,
+ return get_meas_rep_avg(lchan, TDMA_MEAS_FIELD_RXLEV, TDMA_MEAS_DIR_DL, ho_get_hodec2_tdma_meas_set(bts->ho),
ho_get_hodec2_rxlev_avg_win(bts->ho));
}
static int current_rxqual(struct gsm_lchan *lchan)
{
struct gsm_bts *bts = lchan->ts->trx->bts;
- return get_meas_rep_avg(lchan, TDMA_MEAS_FIELD_RXQUAL, TDMA_MEAS_DIR_DL,
- ho_get_hodec2_full_tdma(bts->ho) ? TDMA_MEAS_SET_FULL : TDMA_MEAS_SET_SUB,
+ return get_meas_rep_avg(lchan, TDMA_MEAS_FIELD_RXQUAL, TDMA_MEAS_DIR_DL, ho_get_hodec2_tdma_meas_set(bts->ho),
ho_get_hodec2_rxqual_avg_win(bts->ho));
}
diff --git a/src/osmo-bsc/meas_rep.c b/src/osmo-bsc/meas_rep.c
index 97c30ac1a..776c610df 100644
--- a/src/osmo-bsc/meas_rep.c
+++ b/src/osmo-bsc/meas_rep.c
@@ -81,8 +81,14 @@ unsigned int calc_initial_idx(unsigned int array_size,
}
static inline enum meas_rep_field choose_meas_rep_field(enum tdma_meas_field field, enum tdma_meas_dir dir,
- enum tdma_meas_set set)
+ enum tdma_meas_set set, const struct gsm_meas_rep *meas_rep)
{
+ if (set == TDMA_MEAS_SET_AUTO) {
+ bool dtx_in_use;
+ dtx_in_use = (meas_rep->flags & ((dir == TDMA_MEAS_DIR_UL) ? MEAS_REP_F_UL_DTX : MEAS_REP_F_DL_DTX));
+ set = (dtx_in_use ? TDMA_MEAS_SET_SUB : TDMA_MEAS_SET_FULL);
+ }
+
osmo_static_assert(TDMA_MEAS_FIELD_RXLEV >= 0 && TDMA_MEAS_FIELD_RXLEV <= 1
&& TDMA_MEAS_FIELD_RXQUAL >= 0 && TDMA_MEAS_FIELD_RXQUAL <= 1
&& TDMA_MEAS_DIR_UL >= 0 && TDMA_MEAS_DIR_UL <= 1
@@ -139,7 +145,7 @@ int get_meas_rep_avg(const struct gsm_lchan *lchan,
enum meas_rep_field use_field;
int val;
- use_field = choose_meas_rep_field(field, dir, set);
+ use_field = choose_meas_rep_field(field, dir, set, &lchan->meas_rep[j]);
val = get_field(&lchan->meas_rep[j], use_field);
if (val >= 0) {
@@ -170,7 +176,7 @@ int meas_rep_n_out_of_m_be(const struct gsm_lchan *lchan,
enum meas_rep_field use_field;
int val;
- use_field = choose_meas_rep_field(field, dir, set);
+ use_field = choose_meas_rep_field(field, dir, set, &lchan->meas_rep[j]);
val = get_field(&lchan->meas_rep[j], use_field);
if (val >= be) /* implies that val < 0 will not count */
@@ -182,3 +188,10 @@ int meas_rep_n_out_of_m_be(const struct gsm_lchan *lchan,
return 0;
}
+
+const struct value_string tdma_meas_set_names[] = {
+ { TDMA_MEAS_SET_FULL, "full" },
+ { TDMA_MEAS_SET_SUB, "subset" },
+ { TDMA_MEAS_SET_AUTO, "auto" },
+ {}
+};
diff --git a/tests/bsc/Makefile.am b/tests/bsc/Makefile.am
index a0bbb81b2..2f6677878 100644
--- a/tests/bsc/Makefile.am
+++ b/tests/bsc/Makefile.am
@@ -46,6 +46,7 @@ bsc_test_LDADD = \
$(top_builddir)/src/osmo-bsc/gsm_data.o \
$(top_builddir)/src/osmo-bsc/handover_cfg.o \
$(top_builddir)/src/osmo-bsc/handover_logic.o \
+ $(top_builddir)/src/osmo-bsc/meas_rep.o \
$(top_builddir)/src/osmo-bsc/neighbor_ident.o \
$(top_builddir)/src/osmo-bsc/net_init.o \
$(top_builddir)/src/osmo-bsc/nm_common_fsm.o \
diff --git a/tests/handover_cfg.vty b/tests/handover_cfg.vty
index 4bafd7225..ccb1a6b04 100644
--- a/tests/handover_cfg.vty
+++ b/tests/handover_cfg.vty
@@ -178,7 +178,7 @@ OsmoBSC(config-net)# list
handover2 power budget hysteresis (<0-999>|default)
handover2 maximum distance (<0-9999>|default)
handover2 assignment (0|1|default)
- handover2 tdma-measurement (full|subset|default)
+ handover2 tdma-measurement (auto|full|subset|default)
handover2 min rxlev (<-110--50>|default)
handover2 min rxqual (<0-7>|default)
handover2 afs-bias rxlev (<0-20>|default)
@@ -335,6 +335,7 @@ OsmoBSC(config-net)# handover2 assignment ?
default Use default (0), remove explicit setting on this node
OsmoBSC(config-net)# handover2 tdma-measurement ?
+ auto Use full set when DTX is not in use, use subset when DTX is in use, as indicated by each Measurement Report
full Full set of 102/104 TDMA frames
subset Sub set of 4 TDMA frames (SACCH)
default Use default (subset), remove explicit setting on this node
@@ -553,6 +554,7 @@ OsmoBSC(config-net-bts)# handover2 assignment ?
default Use default (0), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover2 tdma-measurement ?
+ auto Use full set when DTX is not in use, use subset when DTX is in use, as indicated by each Measurement Report
full Full set of 102/104 TDMA frames
subset Sub set of 4 TDMA frames (SACCH)
default Use default (subset), remove explicit setting on this node