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