HO: cfg: separate hodec1 from hodec2 parameters

Do not share config items between the current handover decision and the
upcoming handover_decision_2.

Rename current handover config items to hodec2_* and duplicate the ones
relevant to handover decision algorithm 1 with name prefix of hodec1_*.

I considered moving hodec2 parameters to an entirely separate .c file and
struct, but that causes considerable code bloat. Rather use the nice
handover_cfg net/bts level mechanism as-is, and simply prefix the names.

In the VTY, the hodec1 parameters are configurable by 'handover foo 23'
commands, while the hodec2 parameters are by 'handover2 foo 23'. The generic
VTY commands to enable/disable handover and to choose the algorithm are still
'handover (0|1)' and 'handover algorithm (1|2)'.

(Note, a subsequent commit will rename the 'handover foo' for hodec1 to
'handover1 foo' and add backwards-compat aliases.)

For example, the 'window rxlev averaging 5' command now exists both for
handover decision 1 and handover decision 2, and its values are independent.
This is valid config:

    network
     # set up handover decision algorithm 1
     # (pending rename of these items to 'handover1 ...')
     handover window rxlev averaging 5
     handover window rxlev neighbor averaging 5

     # set up handover decision algorithm 2
     handover2 window rxlev averaging 7
     handover2 window rxlev neighbor averaging 7
     handover2 penalty-time max-distance 10

     # enable handover
     handover 1

     bts 0
      handover algorithm 1
     bts 1
      handover algorithm 2

In this example, bts 0 uses algo 1 with rxlev averaging of 5, while bts 1 uses
algorithm 2 where rxlev averaging of 7 is in effect.

Change-Id: I6475b2543b18d21710a6d774b214cb484f36ec8e
This commit is contained in:
Neels Hofmeyr 2018-02-14 19:56:23 +01:00 committed by Neels Hofmeyr
parent 04cc5d64c6
commit dd42eb9f90
3 changed files with 303 additions and 124 deletions

View File

@ -12,11 +12,12 @@ struct handover_cfg;
struct handover_cfg *ho_cfg_init(void *ctx, struct handover_cfg *higher_level_cfg); struct handover_cfg *ho_cfg_init(void *ctx, struct handover_cfg *higher_level_cfg);
#define HO_CFG_STR_HANDOVER "Handover options\n" #define HO_CFG_STR_HANDOVER1 "Handover options for handover decision algorithm 1\n"
#define HO_CFG_STR_WIN HO_CFG_STR_HANDOVER "Measurement averaging settings\n" #define HO_CFG_STR_HANDOVER2 "Handover options for handover decision algorithm 2\n"
#define HO_CFG_STR_WIN "Measurement averaging settings\n"
#define HO_CFG_STR_WIN_RXLEV HO_CFG_STR_WIN "Received-Level averaging\n" #define HO_CFG_STR_WIN_RXLEV HO_CFG_STR_WIN "Received-Level averaging\n"
#define HO_CFG_STR_WIN_RXQUAL HO_CFG_STR_WIN "Received-Quality averaging\n" #define HO_CFG_STR_WIN_RXQUAL HO_CFG_STR_WIN "Received-Quality averaging\n"
#define HO_CFG_STR_POWER_BUDGET HO_CFG_STR_HANDOVER "Neighbor cell power triggering\n" "Neighbor cell power triggering\n" #define HO_CFG_STR_POWER_BUDGET "Neighbor cell power triggering\n" "Neighbor cell power triggering\n"
#define HO_CFG_STR_AVG_COUNT "Number of values to average over\n" #define HO_CFG_STR_AVG_COUNT "Number of values to average over\n"
#define HO_CFG_STR_2 " (HO algo 2 only)\n" #define HO_CFG_STR_2 " (HO algo 2 only)\n"
#define HO_CFG_STR_MIN "Minimum Level/Quality thresholds before triggering HO" HO_CFG_STR_2 #define HO_CFG_STR_MIN "Minimum Level/Quality thresholds before triggering HO" HO_CFG_STR_2
@ -68,151 +69,210 @@ static inline const char *tdma2a(bool val)
* VTY_WRITE_CONV: function name to convert struct value to VTY_WRITE_FMT, e.g. 'as_is'. * VTY_WRITE_CONV: function name to convert struct value to VTY_WRITE_FMT, e.g. 'as_is'.
* VTY_DOC: VTY documentation strings to match VTY_CMD and VTY_CMD_ARGs. * VTY_DOC: VTY documentation strings to match VTY_CMD and VTY_CMD_ARGs.
*/ */
#define HO_CFG_ALL_MEMBERS \ #define HO_GENERAL_CFG_ALL_MEMBERS \
\ \
HO_CFG_ONE_MEMBER(bool, ho_active, 0, \ HO_CFG_ONE_MEMBER(bool, ho_active, 0, \
"handover", "0|1", a2bool, "%d", bool2i, \ "handover", "0|1", a2bool, "%d", bool2i, \
HO_CFG_STR_HANDOVER \ "Handover general config\n" \
"Disable in-call handover\n" \ "Disable in-call handover\n" \
"Enable in-call handover\n" \ "Enable in-call handover\n" \
"Enable/disable handover: ") \ "Enable/disable handover: ") \
\ \
HO_CFG_ONE_MEMBER(int, algorithm, 1, \ HO_CFG_ONE_MEMBER(int, algorithm, 1, \
"handover algorithm", "1|2", atoi, "%d", as_is, \ "handover algorithm", "1|2", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ "Handover general config\n" \
"Choose algorithm for handover decision\n" \ "Choose algorithm for handover decision\n" \
"Algorithm 1: trigger handover based on comparing current cell and neighbor RxLev and RxQual," \ "Algorithm 1: trigger handover based on comparing current cell and neighbor RxLev and RxQual," \
" only.\n" \ " only.\n" \
"Algorithm 2: trigger handover on RxLev/RxQual, and also to balance the load across several" \ "Algorithm 2: trigger handover on RxLev/RxQual, and also to balance the load across several" \
" cells. Consider available codecs. Prevent repeated handover by penalty timers.\n") \ " cells. Consider available codecs. Prevent repeated handover by penalty timers.\n") \
#define HODEC1_CFG_ALL_MEMBERS \
\ \
HO_CFG_ONE_MEMBER(unsigned int, rxlev_avg_win, 10, \ HO_CFG_ONE_MEMBER(unsigned int, hodec1_rxlev_avg_win, 10, \
"handover window rxlev averaging", "<1-10>", atoi, "%u", as_is, \ "handover window rxlev averaging", "<1-10>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER1 \
HO_CFG_STR_WIN_RXLEV \ HO_CFG_STR_WIN_RXLEV \
"How many RxLev measurements are used for averaging\n" \ "How many RxLev measurements are used for averaging\n" \
"RxLev averaging: " HO_CFG_STR_AVG_COUNT) \ "RxLev averaging: " HO_CFG_STR_AVG_COUNT) \
\ \
HO_CFG_ONE_MEMBER(unsigned int, rxqual_avg_win, 1, \ HO_CFG_ONE_MEMBER(unsigned int, hodec1_rxqual_avg_win, 1, \
"handover window rxqual averaging", "<1-10>", atoi, "%u", as_is, \ "handover window rxqual averaging", "<1-10>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER1 \
HO_CFG_STR_WIN_RXQUAL \ HO_CFG_STR_WIN_RXQUAL \
"How many RxQual measurements are used for averaging\n" \ "How many RxQual measurements are used for averaging\n" \
"RxQual averaging: " HO_CFG_STR_AVG_COUNT) \ "RxQual averaging: " HO_CFG_STR_AVG_COUNT) \
\ \
HO_CFG_ONE_MEMBER(unsigned int, rxlev_neigh_avg_win, 10, \ HO_CFG_ONE_MEMBER(unsigned int, hodec1_rxlev_neigh_avg_win, 10, \
"handover window rxlev neighbor averaging", "<1-10>", atoi, "%u", as_is, \ "handover window rxlev neighbor averaging", "<1-10>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER1 \
HO_CFG_STR_WIN_RXLEV \ HO_CFG_STR_WIN_RXLEV \
"How many Neighbor RxLev measurements are used for averaging\n" \ "How many Neighbor RxLev measurements are used for averaging\n" \
"How many Neighbor RxLev measurements are used for averaging\n" \ "How many Neighbor RxLev measurements are used for averaging\n" \
"Neighbor RxLev averaging: " HO_CFG_STR_AVG_COUNT) \ "Neighbor RxLev averaging: " HO_CFG_STR_AVG_COUNT) \
\ \
HO_CFG_ONE_MEMBER(unsigned int, pwr_interval, 6, \ HO_CFG_ONE_MEMBER(unsigned int, hodec1_pwr_interval, 6, \
"handover power budget interval", "<1-99>", atoi, "%u", as_is, \ "handover power budget interval", "<1-99>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER1 \
HO_CFG_STR_POWER_BUDGET \ HO_CFG_STR_POWER_BUDGET \
"How often to check for a better cell (SACCH frames)\n" \ "How often to check for a better cell (SACCH frames)\n" \
"Check for stronger neighbor every N number of SACCH frames\n") \ "Check for stronger neighbor every N number of SACCH frames\n") \
\ \
HO_CFG_ONE_MEMBER(unsigned int, pwr_hysteresis, 3, \ HO_CFG_ONE_MEMBER(unsigned int, hodec1_pwr_hysteresis, 3, \
"handover power budget hysteresis", "<0-999>", atoi, "%u", as_is, \ "handover power budget hysteresis", "<0-999>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER1 \
HO_CFG_STR_POWER_BUDGET \ HO_CFG_STR_POWER_BUDGET \
"How many dBm stronger must a neighbor be to become a HO candidate\n" \ "How many dBm stronger must a neighbor be to become a HO candidate\n" \
"Neighbor's strength difference in dBm\n") \ "Neighbor's strength difference in dBm\n") \
\ \
HO_CFG_ONE_MEMBER(unsigned int, max_distance, 9999, \ HO_CFG_ONE_MEMBER(unsigned int, hodec1_max_distance, 9999, \
"handover maximum distance" , "<0-9999>", atoi, "%u", as_is, \ "handover maximum distance" , "<0-9999>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER1 \
"Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n" \
"Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n" \
"Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n") \
#define HODEC2_CFG_ALL_MEMBERS \
\
HO_CFG_ONE_MEMBER(unsigned int, hodec2_rxlev_avg_win, 10, \
"handover2 window rxlev averaging", "<1-10>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_WIN_RXLEV \
"How many RxLev measurements are used for averaging\n" \
"RxLev averaging: " HO_CFG_STR_AVG_COUNT) \
\
HO_CFG_ONE_MEMBER(unsigned int, hodec2_rxqual_avg_win, 1, \
"handover2 window rxqual averaging", "<1-10>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_WIN_RXQUAL \
"How many RxQual measurements are used for averaging\n" \
"RxQual averaging: " HO_CFG_STR_AVG_COUNT) \
\
HO_CFG_ONE_MEMBER(unsigned int, hodec2_rxlev_neigh_avg_win, 10, \
"handover2 window rxlev neighbor averaging", "<1-10>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_WIN_RXLEV \
"How many Neighbor RxLev measurements are used for averaging\n" \
"How many Neighbor RxLev measurements are used for averaging\n" \
"Neighbor RxLev averaging: " HO_CFG_STR_AVG_COUNT) \
\
HO_CFG_ONE_MEMBER(unsigned int, hodec2_pwr_interval, 6, \
"handover2 power budget interval", "<1-99>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_POWER_BUDGET \
"How often to check for a better cell (SACCH frames)\n" \
"Check for stronger neighbor every N number of SACCH frames\n") \
\
HO_CFG_ONE_MEMBER(unsigned int, hodec2_pwr_hysteresis, 3, \
"handover2 power budget hysteresis", "<0-999>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_POWER_BUDGET \
"How many dBm stronger must a neighbor be to become a HO candidate\n" \
"Neighbor's strength difference in dBm\n") \
\
HO_CFG_ONE_MEMBER(unsigned int, hodec2_max_distance, 9999, \
"handover2 maximum distance" , "<0-9999>", atoi, "%u", as_is, \
HO_CFG_STR_HANDOVER2 \
"Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n" \ "Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n" \
"Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n" \ "Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n" \
"Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n") \ "Maximum Timing-Advance value (i.e. MS distance) before triggering HO\n") \
\ \
HO_CFG_ONE_MEMBER(bool, as_active, 0, \ HO_CFG_ONE_MEMBER(bool, hodec2_as_active, 0, \
"handover assignment", "0|1", a2bool, "%d", bool2i, \ "handover2 assignment", "0|1", a2bool, "%d", bool2i, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
"Enable or disable in-call channel re-assignment" HO_CFG_STR_2 \ "Enable or disable in-call channel re-assignment" HO_CFG_STR_2 \
"Disable in-call assignment\n" \ "Disable in-call assignment\n" \
"Enable in-call assignment\n") \ "Enable in-call assignment\n") \
\ \
HO_CFG_ONE_MEMBER(bool, full_tdma, subset, \ HO_CFG_ONE_MEMBER(bool, hodec2_full_tdma, subset, \
"handover tdma-measurement", "full|subset", a2tdma, "%s", tdma2a, \ "handover2 tdma-measurement", "full|subset", a2tdma, "%s", tdma2a, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
"Define measurement set of TDMA frames" HO_CFG_STR_2 \ "Define measurement set of TDMA frames" HO_CFG_STR_2 \
"Full set of 102/104 TDMA frames\n" \ "Full set of 102/104 TDMA frames\n" \
"Sub set of 4 TDMA frames (SACCH)\n") \ "Sub set of 4 TDMA frames (SACCH)\n") \
\ \
HO_CFG_ONE_MEMBER(int, min_rxlev, -100, \ HO_CFG_ONE_MEMBER(int, hodec2_min_rxlev, -100, \
"handover min rxlev", "<-110--50>", atoi, "%d", as_is, \ "handover2 min rxlev", "<-110--50>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_MIN \ HO_CFG_STR_MIN \
"How weak may RxLev of an MS become before triggering HO\n" \ "How weak may RxLev of an MS become before triggering HO\n" \
"minimum RxLev (dBm)\n") \ "minimum RxLev (dBm)\n") \
\ \
HO_CFG_ONE_MEMBER(int, min_rxqual, 5, \ HO_CFG_ONE_MEMBER(int, hodec2_min_rxqual, 5, \
"handover min rxqual", "<0-7>", atoi, "%d", as_is, \ "handover2 min rxqual", "<0-7>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_MIN \ HO_CFG_STR_MIN \
"How bad may RxQual of an MS become before triggering HO\n" \ "How bad may RxQual of an MS become before triggering HO\n" \
"minimum RxQual (dBm)\n") \ "minimum RxQual (dBm)\n") \
\ \
HO_CFG_ONE_MEMBER(int, afs_bias_rxlev, 0, \ HO_CFG_ONE_MEMBER(int, hodec2_afs_bias_rxlev, 0, \
"handover afs-bias rxlev", "<0-20>", atoi, "%d", as_is, \ "handover2 afs-bias rxlev", "<0-20>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_AFS_BIAS \ HO_CFG_STR_AFS_BIAS \
"RxLev improvement bias for AFS over other codecs\n" \ "RxLev improvement bias for AFS over other codecs\n" \
"Virtual RxLev improvement (dBm)\n") \ "Virtual RxLev improvement (dBm)\n") \
\ \
HO_CFG_ONE_MEMBER(int, afs_bias_rxqual, 0, \ HO_CFG_ONE_MEMBER(int, hodec2_afs_bias_rxqual, 0, \
"handover afs-bias rxqual", "<0-7>", atoi, "%d", as_is, \ "handover2 afs-bias rxqual", "<0-7>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_AFS_BIAS \ HO_CFG_STR_AFS_BIAS \
"RxQual improvement bias for AFS over other codecs\n" \ "RxQual improvement bias for AFS over other codecs\n" \
"Virtual RxQual improvement (dBm)\n") \ "Virtual RxQual improvement (dBm)\n") \
\ \
HO_CFG_ONE_MEMBER(int, tchf_min_slots, 0, \ HO_CFG_ONE_MEMBER(int, hodec2_tchf_min_slots, 0, \
"handover min-free-slots tch/f", "<0-9999>", atoi, "%d", as_is, \ "handover2 min-free-slots tch/f", "<0-9999>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_MIN_TCH \ HO_CFG_STR_MIN_TCH \
"Minimum free TCH/F timeslots before cell is considered congested\n" \ "Minimum free TCH/F timeslots before cell is considered congested\n" \
"Number of TCH/F slots\n") \ "Number of TCH/F slots\n") \
\ \
HO_CFG_ONE_MEMBER(int, tchh_min_slots, 0, \ HO_CFG_ONE_MEMBER(int, hodec2_tchh_min_slots, 0, \
"handover min-free-slots tch/h", "<0-9999>", atoi, "%d", as_is, \ "handover2 min-free-slots tch/h", "<0-9999>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_MIN_TCH \ HO_CFG_STR_MIN_TCH \
"Minimum free TCH/H timeslots before cell is considered congested\n" \ "Minimum free TCH/H timeslots before cell is considered congested\n" \
"Number of TCH/H slots\n") \ "Number of TCH/H slots\n") \
\ \
HO_CFG_ONE_MEMBER(int, ho_max, 9999, \ HO_CFG_ONE_MEMBER(int, hodec2_ho_max, 9999, \
"handover max-handovers", "<1-9999>", atoi, "%d", as_is, \ "handover2 max-handovers", "<1-9999>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
"Maximum number of concurrent handovers allowed per cell" HO_CFG_STR_2 \ "Maximum number of concurrent handovers allowed per cell" HO_CFG_STR_2 \
"Number\n") \ "Number\n") \
\ \
HO_CFG_ONE_MEMBER(int, penalty_max_dist, 300, \ HO_CFG_ONE_MEMBER(int, hodec2_penalty_max_dist, 300, \
"handover penalty-time max-distance", "<0-99999>", atoi, "%d", as_is, \ "handover2 penalty-time max-distance", "<0-99999>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_PENALTY_TIME \ HO_CFG_STR_PENALTY_TIME \
"Time to suspend handovers after leaving this cell due to exceeding max distance\n" \ "Time to suspend handovers after leaving this cell due to exceeding max distance\n" \
"Seconds\n") \ "Seconds\n") \
\ \
HO_CFG_ONE_MEMBER(int, penalty_failed_ho, 60, \ HO_CFG_ONE_MEMBER(int, hodec2_penalty_failed_ho, 60, \
"handover penalty-time failed-ho", "<0-99999>", atoi, "%d", as_is, \ "handover2 penalty-time failed-ho", "<0-99999>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_PENALTY_TIME \ HO_CFG_STR_PENALTY_TIME \
"Time to suspend handovers after handover failure to this cell\n" \ "Time to suspend handovers after handover failure to this cell\n" \
"Seconds\n") \ "Seconds\n") \
\ \
HO_CFG_ONE_MEMBER(int, penalty_failed_as, 60, \ HO_CFG_ONE_MEMBER(int, hodec2_penalty_failed_as, 60, \
"handover penalty-time failed-assignment", "<0-99999>", atoi, "%d", as_is, \ "handover2 penalty-time failed-assignment", "<0-99999>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
HO_CFG_STR_PENALTY_TIME \ HO_CFG_STR_PENALTY_TIME \
"Time to suspend handovers after assignment failure in this cell\n" \ "Time to suspend handovers after assignment failure in this cell\n" \
"Seconds\n") \ "Seconds\n") \
\ \
HO_CFG_ONE_MEMBER(int, retries, 0, \ HO_CFG_ONE_MEMBER(int, hodec2_retries, 0, \
"handover retries", "<0-9>", atoi, "%d", as_is, \ "handover2 retries", "<0-9>", atoi, "%d", as_is, \
HO_CFG_STR_HANDOVER \ HO_CFG_STR_HANDOVER2 \
"Immediately retry on handover/assignment failure" HO_CFG_STR_2 \ "Immediately retry on handover/assignment failure" HO_CFG_STR_2 \
"Number of retries\n") \ "Number of retries\n") \
#define HO_CFG_ALL_MEMBERS \
HO_GENERAL_CFG_ALL_MEMBERS \
HODEC1_CFG_ALL_MEMBERS \
HODEC2_CFG_ALL_MEMBERS \
/* Declare public API for handover cfg parameters... */ /* Declare public API for handover cfg parameters... */

View File

@ -215,10 +215,10 @@ static int attempt_handover(struct gsm_meas_rep *mr)
continue; continue;
/* caculate average rxlev for this cell over the window */ /* caculate average rxlev for this cell over the window */
avg = neigh_meas_avg(nmp, ho_get_rxlev_neigh_avg_win(bts->ho)); avg = neigh_meas_avg(nmp, ho_get_hodec1_rxlev_neigh_avg_win(bts->ho));
/* check if hysteresis is fulfilled */ /* check if hysteresis is fulfilled */
if (avg < mr->dl.full.rx_lev + ho_get_pwr_hysteresis(bts->ho)) if (avg < mr->dl.full.rx_lev + ho_get_hodec1_pwr_hysteresis(bts->ho))
continue; continue;
better = avg - mr->dl.full.rx_lev; better = avg - mr->dl.full.rx_lev;
@ -290,7 +290,7 @@ static int process_meas_rep(struct gsm_meas_rep *mr)
process_meas_neigh(mr); process_meas_neigh(mr);
av_rxlev = get_meas_rep_avg(mr->lchan, dlev, av_rxlev = get_meas_rep_avg(mr->lchan, dlev,
ho_get_rxlev_avg_win(bts->ho)); ho_get_hodec1_rxlev_avg_win(bts->ho));
/* Interference HO */ /* Interference HO */
if (rxlev2dbm(av_rxlev) > -85 && if (rxlev2dbm(av_rxlev) > -85 &&
@ -313,14 +313,14 @@ static int process_meas_rep(struct gsm_meas_rep *mr)
} }
/* Distance */ /* Distance */
if (mr->ms_l1.ta > ho_get_max_distance(bts->ho)) { if (mr->ms_l1.ta > ho_get_hodec1_max_distance(bts->ho)) {
LOGPC(DHO, LOGL_INFO, "HO cause: Distance av_rxlev=%d dBm ta=%d \n", LOGPC(DHO, LOGL_INFO, "HO cause: Distance av_rxlev=%d dBm ta=%d \n",
rxlev2dbm(av_rxlev), mr->ms_l1.ta); rxlev2dbm(av_rxlev), mr->ms_l1.ta);
return attempt_handover(mr); return attempt_handover(mr);
} }
/* Power Budget AKA Better Cell */ /* Power Budget AKA Better Cell */
pwr_interval = ho_get_pwr_interval(bts->ho); pwr_interval = ho_get_hodec1_pwr_interval(bts->ho);
/* handover_cfg.h defines pwr_interval as [1..99], but since we're using it in a modulo below, /* handover_cfg.h defines pwr_interval as [1..99], but since we're using it in a modulo below,
* assert non-zero to clarify. */ * assert non-zero to clarify. */
OSMO_ASSERT(pwr_interval); OSMO_ASSERT(pwr_interval);

View File

@ -144,19 +144,19 @@ network
... !handover ... !handover
OsmoBSC(config-net-bts)# ### Verify that 'min rxlev' value range stops at -50 OsmoBSC(config-net-bts)# ### Verify that 'min rxlev' value range stops at -50
OsmoBSC(config-net-bts)# handover min rxlev ? OsmoBSC(config-net-bts)# handover2 min rxlev ?
<-110--50> minimum RxLev (dBm) <-110--50> minimum RxLev (dBm)
default Use default (-100), remove explicit setting on this node default Use default (-100), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover min rxlev -111 OsmoBSC(config-net-bts)# handover2 min rxlev -111
% Unknown command. % Unknown command.
OsmoBSC(config-net-bts)# handover min rxlev -110 OsmoBSC(config-net-bts)# handover2 min rxlev -110
OsmoBSC(config-net-bts)# handover min rxlev -50 OsmoBSC(config-net-bts)# handover2 min rxlev -50
OsmoBSC(config-net-bts)# handover min rxlev -49 OsmoBSC(config-net-bts)# handover2 min rxlev -49
% Unknown command. % Unknown command.
OsmoBSC(config-net-bts)# handover min rxlev 50 OsmoBSC(config-net-bts)# handover2 min rxlev 50
% Unknown command. % Unknown command.
OsmoBSC(config-net-bts)# handover min rxlev default OsmoBSC(config-net-bts)# handover2 min rxlev default
% 'handover min rxlev' setting removed, now is -100 % 'handover2 min rxlev' setting removed, now is -100
OsmoBSC(config-net-bts)# ### Checking online help OsmoBSC(config-net-bts)# ### Checking online help
@ -171,23 +171,32 @@ OsmoBSC(config-net)# list
handover power budget interval (<1-99>|default) handover power budget interval (<1-99>|default)
handover power budget hysteresis (<0-999>|default) handover power budget hysteresis (<0-999>|default)
handover maximum distance (<0-9999>|default) handover maximum distance (<0-9999>|default)
handover assignment (0|1|default) handover2 window rxlev averaging (<1-10>|default)
handover tdma-measurement (full|subset|default) handover2 window rxqual averaging (<1-10>|default)
handover min rxlev (<-110--50>|default) handover2 window rxlev neighbor averaging (<1-10>|default)
handover min rxqual (<0-7>|default) handover2 power budget interval (<1-99>|default)
handover afs-bias rxlev (<0-20>|default) handover2 power budget hysteresis (<0-999>|default)
handover afs-bias rxqual (<0-7>|default) handover2 maximum distance (<0-9999>|default)
handover min-free-slots tch/f (<0-9999>|default) handover2 assignment (0|1|default)
handover min-free-slots tch/h (<0-9999>|default) handover2 tdma-measurement (full|subset|default)
handover max-handovers (<1-9999>|default) handover2 min rxlev (<-110--50>|default)
handover penalty-time max-distance (<0-99999>|default) handover2 min rxqual (<0-7>|default)
handover penalty-time failed-ho (<0-99999>|default) handover2 afs-bias rxlev (<0-20>|default)
handover penalty-time failed-assignment (<0-99999>|default) handover2 afs-bias rxqual (<0-7>|default)
handover retries (<0-9>|default) handover2 min-free-slots tch/f (<0-9999>|default)
handover2 min-free-slots tch/h (<0-9999>|default)
handover2 max-handovers (<1-9999>|default)
handover2 penalty-time max-distance (<0-99999>|default)
handover2 penalty-time failed-ho (<0-99999>|default)
handover2 penalty-time failed-assignment (<0-99999>|default)
handover2 retries (<0-9>|default)
... ...
OsmoBSC(config-net)# handover? OsmoBSC(config-net)# handover?
handover Handover options handover Handover general config
OsmoBSC(config-net)# handover2?
handover2 Handover options for handover decision algorithm 2
OsmoBSC(config-net)# handover ? OsmoBSC(config-net)# handover ?
0 Disable in-call handover 0 Disable in-call handover
@ -197,6 +206,11 @@ OsmoBSC(config-net)# handover ?
window Measurement averaging settings window Measurement averaging settings
power Neighbor cell power triggering power Neighbor cell power triggering
maximum Maximum Timing-Advance value (i.e. MS distance) before triggering HO maximum Maximum Timing-Advance value (i.e. MS distance) before triggering HO
OsmoBSC(config-net)# handover2 ?
window Measurement averaging settings
power Neighbor cell power triggering
maximum Maximum Timing-Advance value (i.e. MS distance) before triggering HO
assignment Enable or disable in-call channel re-assignment (HO algo 2 only) assignment Enable or disable in-call channel re-assignment (HO algo 2 only)
tdma-measurement Define measurement set of TDMA frames (HO algo 2 only) tdma-measurement Define measurement set of TDMA frames (HO algo 2 only)
min Minimum Level/Quality thresholds before triggering HO (HO algo 2 only) min Minimum Level/Quality thresholds before triggering HO (HO algo 2 only)
@ -259,85 +273,137 @@ OsmoBSC(config-net)# handover maximum distance ?
<0-9999> Maximum Timing-Advance value (i.e. MS distance) before triggering HO <0-9999> Maximum Timing-Advance value (i.e. MS distance) before triggering HO
default Use default (9999), remove explicit setting on this node default Use default (9999), remove explicit setting on this node
OsmoBSC(config-net)# handover assignment ? OsmoBSC(config-net)# handover2 window ?
rxlev Received-Level averaging
rxqual Received-Quality averaging
OsmoBSC(config-net)# handover2 window rxlev ?
averaging How many RxLev measurements are used for averaging
neighbor How many Neighbor RxLev measurements are used for averaging
OsmoBSC(config-net)# handover2 window rxlev averaging ?
<1-10> RxLev averaging: Number of values to average over
default Use default (10), remove explicit setting on this node
OsmoBSC(config-net)# handover2 window rxlev neighbor ?
averaging How many Neighbor RxLev measurements are used for averaging
OsmoBSC(config-net)# handover2 window rxlev neighbor averaging ?
<1-10> Neighbor RxLev averaging: Number of values to average over
default Use default (10), remove explicit setting on this node
OsmoBSC(config-net)# handover2 window rxqual ?
averaging How many RxQual measurements are used for averaging
OsmoBSC(config-net)# handover2 window rxqual averaging ?
<1-10> RxQual averaging: Number of values to average over
default Use default (1), remove explicit setting on this node
OsmoBSC(config-net)# handover2 power ?
budget Neighbor cell power triggering
OsmoBSC(config-net)# handover2 power budget ?
interval How often to check for a better cell (SACCH frames)
hysteresis How many dBm stronger must a neighbor be to become a HO candidate
OsmoBSC(config-net)# handover2 power budget interval ?
<1-99> Check for stronger neighbor every N number of SACCH frames
default Use default (6), remove explicit setting on this node
OsmoBSC(config-net)# handover2 power budget hysteresis ?
<0-999> Neighbor's strength difference in dBm
default Use default (3), remove explicit setting on this node
OsmoBSC(config-net)# handover2 maximum ?
distance Maximum Timing-Advance value (i.e. MS distance) before triggering HO
OsmoBSC(config-net)# handover2 maximum distance ?
<0-9999> Maximum Timing-Advance value (i.e. MS distance) before triggering HO
default Use default (9999), remove explicit setting on this node
OsmoBSC(config-net)# handover2 assignment ?
0 Disable in-call assignment 0 Disable in-call assignment
1 Enable in-call assignment 1 Enable in-call assignment
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net)# handover tdma-measurement ? OsmoBSC(config-net)# handover2 tdma-measurement ?
full Full set of 102/104 TDMA frames full Full set of 102/104 TDMA frames
subset Sub set of 4 TDMA frames (SACCH) subset Sub set of 4 TDMA frames (SACCH)
default Use default (subset), remove explicit setting on this node default Use default (subset), remove explicit setting on this node
OsmoBSC(config-net)# handover min ? OsmoBSC(config-net)# handover2 min ?
rxlev How weak may RxLev of an MS become before triggering HO rxlev How weak may RxLev of an MS become before triggering HO
rxqual How bad may RxQual of an MS become before triggering HO rxqual How bad may RxQual of an MS become before triggering HO
OsmoBSC(config-net)# handover min rxlev ? OsmoBSC(config-net)# handover2 min rxlev ?
<-110--50> minimum RxLev (dBm) <-110--50> minimum RxLev (dBm)
default Use default (-100), remove explicit setting on this node default Use default (-100), remove explicit setting on this node
OsmoBSC(config-net)# handover min rxqual ? OsmoBSC(config-net)# handover2 min rxqual ?
<0-7> minimum RxQual (dBm) <0-7> minimum RxQual (dBm)
default Use default (5), remove explicit setting on this node default Use default (5), remove explicit setting on this node
OsmoBSC(config-net)# handover afs-bias ? OsmoBSC(config-net)# handover2 afs-bias ?
rxlev RxLev improvement bias for AFS over other codecs rxlev RxLev improvement bias for AFS over other codecs
rxqual RxQual improvement bias for AFS over other codecs rxqual RxQual improvement bias for AFS over other codecs
OsmoBSC(config-net)# handover afs-bias rxlev ? OsmoBSC(config-net)# handover2 afs-bias rxlev ?
<0-20> Virtual RxLev improvement (dBm) <0-20> Virtual RxLev improvement (dBm)
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net)# handover afs-bias rxqual ? OsmoBSC(config-net)# handover2 afs-bias rxqual ?
<0-7> Virtual RxQual improvement (dBm) <0-7> Virtual RxQual improvement (dBm)
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net)# handover min-free-slots ? OsmoBSC(config-net)# handover2 min-free-slots ?
tch/f Minimum free TCH/F timeslots before cell is considered congested tch/f Minimum free TCH/F timeslots before cell is considered congested
tch/h Minimum free TCH/H timeslots before cell is considered congested tch/h Minimum free TCH/H timeslots before cell is considered congested
OsmoBSC(config-net)# handover min-free-slots tch/f ? OsmoBSC(config-net)# handover2 min-free-slots tch/f ?
<0-9999> Number of TCH/F slots <0-9999> Number of TCH/F slots
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net)# handover min-free-slots TCH/F ? OsmoBSC(config-net)# handover2 min-free-slots TCH/F ?
% There is no matched command. % There is no matched command.
OsmoBSC(config-net)# handover min-free-slots tch/h ? OsmoBSC(config-net)# handover2 min-free-slots tch/h ?
<0-9999> Number of TCH/H slots <0-9999> Number of TCH/H slots
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net)# handover max-handovers ? OsmoBSC(config-net)# handover2 max-handovers ?
<1-9999> Number <1-9999> Number
default Use default (9999), remove explicit setting on this node default Use default (9999), remove explicit setting on this node
OsmoBSC(config-net)# handover penalty-time ? OsmoBSC(config-net)# handover2 penalty-time ?
max-distance Time to suspend handovers after leaving this cell due to exceeding max distance max-distance Time to suspend handovers after leaving this cell due to exceeding max distance
failed-ho Time to suspend handovers after handover failure to this cell failed-ho Time to suspend handovers after handover failure to this cell
failed-assignment Time to suspend handovers after assignment failure in this cell failed-assignment Time to suspend handovers after assignment failure in this cell
OsmoBSC(config-net)# handover penalty-time max-distance ? OsmoBSC(config-net)# handover2 penalty-time max-distance ?
<0-99999> Seconds <0-99999> Seconds
default Use default (300), remove explicit setting on this node default Use default (300), remove explicit setting on this node
OsmoBSC(config-net)# handover penalty-time failed-ho ? OsmoBSC(config-net)# handover2 penalty-time failed-ho ?
<0-99999> Seconds <0-99999> Seconds
default Use default (60), remove explicit setting on this node default Use default (60), remove explicit setting on this node
OsmoBSC(config-net)# handover penalty-time failed-assignment ? OsmoBSC(config-net)# handover2 penalty-time failed-assignment ?
<0-99999> Seconds <0-99999> Seconds
default Use default (60), remove explicit setting on this node default Use default (60), remove explicit setting on this node
OsmoBSC(config-net)# handover retries ? OsmoBSC(config-net)# handover2 retries ?
<0-9> Number of retries <0-9> Number of retries
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net)# ### Same on BTS level OsmoBSC(config-net)# ### Same on BTS level
OsmoBSC(config-net)# bts 0 OsmoBSC(config-net)# bts 0
OsmoBSC(config-net-bts)# handover? OsmoBSC(config-net-bts)# handover?
handover Handover options handover Handover general config
OsmoBSC(config-net-bts)# handover2?
handover2 Handover options for handover decision algorithm 2
OsmoBSC(config-net-bts)# handover ? OsmoBSC(config-net-bts)# handover ?
0 Disable in-call handover 0 Disable in-call handover
@ -347,6 +413,11 @@ OsmoBSC(config-net-bts)# handover ?
window Measurement averaging settings window Measurement averaging settings
power Neighbor cell power triggering power Neighbor cell power triggering
maximum Maximum Timing-Advance value (i.e. MS distance) before triggering HO maximum Maximum Timing-Advance value (i.e. MS distance) before triggering HO
OsmoBSC(config-net-bts)# handover2 ?
window Measurement averaging settings
power Neighbor cell power triggering
maximum Maximum Timing-Advance value (i.e. MS distance) before triggering HO
assignment Enable or disable in-call channel re-assignment (HO algo 2 only) assignment Enable or disable in-call channel re-assignment (HO algo 2 only)
tdma-measurement Define measurement set of TDMA frames (HO algo 2 only) tdma-measurement Define measurement set of TDMA frames (HO algo 2 only)
min Minimum Level/Quality thresholds before triggering HO (HO algo 2 only) min Minimum Level/Quality thresholds before triggering HO (HO algo 2 only)
@ -409,76 +480,124 @@ OsmoBSC(config-net-bts)# handover maximum distance ?
<0-9999> Maximum Timing-Advance value (i.e. MS distance) before triggering HO <0-9999> Maximum Timing-Advance value (i.e. MS distance) before triggering HO
default Use default (9999), remove explicit setting on this node default Use default (9999), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover assignment ? OsmoBSC(config-net-bts)# handover2 window ?
rxlev Received-Level averaging
rxqual Received-Quality averaging
OsmoBSC(config-net-bts)# handover2 window rxlev ?
averaging How many RxLev measurements are used for averaging
neighbor How many Neighbor RxLev measurements are used for averaging
OsmoBSC(config-net-bts)# handover2 window rxlev averaging ?
<1-10> RxLev averaging: Number of values to average over
default Use default (10), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover2 window rxlev neighbor ?
averaging How many Neighbor RxLev measurements are used for averaging
OsmoBSC(config-net-bts)# handover2 window rxlev neighbor averaging ?
<1-10> Neighbor RxLev averaging: Number of values to average over
default Use default (10), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover2 window rxqual ?
averaging How many RxQual measurements are used for averaging
OsmoBSC(config-net-bts)# handover2 window rxqual averaging ?
<1-10> RxQual averaging: Number of values to average over
default Use default (1), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover2 power ?
budget Neighbor cell power triggering
OsmoBSC(config-net-bts)# handover2 power budget ?
interval How often to check for a better cell (SACCH frames)
hysteresis How many dBm stronger must a neighbor be to become a HO candidate
OsmoBSC(config-net-bts)# handover2 power budget interval ?
<1-99> Check for stronger neighbor every N number of SACCH frames
default Use default (6), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover2 power budget hysteresis ?
<0-999> Neighbor's strength difference in dBm
default Use default (3), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover2 maximum ?
distance Maximum Timing-Advance value (i.e. MS distance) before triggering HO
OsmoBSC(config-net-bts)# handover2 maximum distance ?
<0-9999> Maximum Timing-Advance value (i.e. MS distance) before triggering HO
default Use default (9999), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover2 assignment ?
0 Disable in-call assignment 0 Disable in-call assignment
1 Enable in-call assignment 1 Enable in-call assignment
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover tdma-measurement ? OsmoBSC(config-net-bts)# handover2 tdma-measurement ?
full Full set of 102/104 TDMA frames full Full set of 102/104 TDMA frames
subset Sub set of 4 TDMA frames (SACCH) subset Sub set of 4 TDMA frames (SACCH)
default Use default (subset), remove explicit setting on this node default Use default (subset), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover min ? OsmoBSC(config-net-bts)# handover2 min ?
rxlev How weak may RxLev of an MS become before triggering HO rxlev How weak may RxLev of an MS become before triggering HO
rxqual How bad may RxQual of an MS become before triggering HO rxqual How bad may RxQual of an MS become before triggering HO
OsmoBSC(config-net-bts)# handover min rxlev ? OsmoBSC(config-net-bts)# handover2 min rxlev ?
<-110--50> minimum RxLev (dBm) <-110--50> minimum RxLev (dBm)
default Use default (-100), remove explicit setting on this node default Use default (-100), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover min rxqual ? OsmoBSC(config-net-bts)# handover2 min rxqual ?
<0-7> minimum RxQual (dBm) <0-7> minimum RxQual (dBm)
default Use default (5), remove explicit setting on this node default Use default (5), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover afs-bias ? OsmoBSC(config-net-bts)# handover2 afs-bias ?
rxlev RxLev improvement bias for AFS over other codecs rxlev RxLev improvement bias for AFS over other codecs
rxqual RxQual improvement bias for AFS over other codecs rxqual RxQual improvement bias for AFS over other codecs
OsmoBSC(config-net-bts)# handover afs-bias rxlev ? OsmoBSC(config-net-bts)# handover2 afs-bias rxlev ?
<0-20> Virtual RxLev improvement (dBm) <0-20> Virtual RxLev improvement (dBm)
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover afs-bias rxqual ? OsmoBSC(config-net-bts)# handover2 afs-bias rxqual ?
<0-7> Virtual RxQual improvement (dBm) <0-7> Virtual RxQual improvement (dBm)
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover min-free-slots ? OsmoBSC(config-net-bts)# handover2 min-free-slots ?
tch/f Minimum free TCH/F timeslots before cell is considered congested tch/f Minimum free TCH/F timeslots before cell is considered congested
tch/h Minimum free TCH/H timeslots before cell is considered congested tch/h Minimum free TCH/H timeslots before cell is considered congested
OsmoBSC(config-net-bts)# handover min-free-slots tch/f ? OsmoBSC(config-net-bts)# handover2 min-free-slots tch/f ?
<0-9999> Number of TCH/F slots <0-9999> Number of TCH/F slots
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover min-free-slots TCH/F ? OsmoBSC(config-net-bts)# handover2 min-free-slots TCH/F ?
% There is no matched command. % There is no matched command.
OsmoBSC(config-net-bts)# handover min-free-slots tch/h ? OsmoBSC(config-net-bts)# handover2 min-free-slots tch/h ?
<0-9999> Number of TCH/H slots <0-9999> Number of TCH/H slots
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover max-handovers ? OsmoBSC(config-net-bts)# handover2 max-handovers ?
<1-9999> Number <1-9999> Number
default Use default (9999), remove explicit setting on this node default Use default (9999), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover penalty-time ? OsmoBSC(config-net-bts)# handover2 penalty-time ?
max-distance Time to suspend handovers after leaving this cell due to exceeding max distance max-distance Time to suspend handovers after leaving this cell due to exceeding max distance
failed-ho Time to suspend handovers after handover failure to this cell failed-ho Time to suspend handovers after handover failure to this cell
failed-assignment Time to suspend handovers after assignment failure in this cell failed-assignment Time to suspend handovers after assignment failure in this cell
OsmoBSC(config-net-bts)# handover penalty-time max-distance ? OsmoBSC(config-net-bts)# handover2 penalty-time max-distance ?
<0-99999> Seconds <0-99999> Seconds
default Use default (300), remove explicit setting on this node default Use default (300), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover penalty-time failed-ho ? OsmoBSC(config-net-bts)# handover2 penalty-time failed-ho ?
<0-99999> Seconds <0-99999> Seconds
default Use default (60), remove explicit setting on this node default Use default (60), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover penalty-time failed-assignment ? OsmoBSC(config-net-bts)# handover2 penalty-time failed-assignment ?
<0-99999> Seconds <0-99999> Seconds
default Use default (60), remove explicit setting on this node default Use default (60), remove explicit setting on this node
OsmoBSC(config-net-bts)# handover retries ? OsmoBSC(config-net-bts)# handover2 retries ?
<0-9> Number of retries <0-9> Number of retries
default Use default (0), remove explicit setting on this node default Use default (0), remove explicit setting on this node