aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc/handover_decision_2.c
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2021-03-09 17:11:45 +0100
committerNeels Hofmeyr <neels@hofmeyr.de>2021-03-24 21:22:21 +0100
commit764449ec2ea6d6b45239278eae90613df8c93f59 (patch)
treef25eeef115083e20eaa7c4713b18d1889e7b865e /src/osmo-bsc/handover_decision_2.c
parentdc60505bc585b1d5f61aa7190b3a2f14fecacaa1 (diff)
fix/refactor neighbor config
The neighbor configuration storage is fundamentally broken: it requires all local cells to be configured before being able to list them as neighbors of each other. Upon config write-back, the neighbor config however is placed back inline with the other config, and hence a written-out neighbor config no longer works on program restart. The cause of this problem is that the config is stored as explicit pointers between local cells (struct gsm_bts), which of course requires the pointer to exist before being able to reference it. Instead, store the actual configuration that the user entered as-is, without pointers or references to objects that need to be ready. Resolve the neighbors every time a neighbor is needed. Hence the user may enter any config at any place in the config file, even non-working config (like a BTS number that doesn't exist), and the relation to actual local or remote neighbor cells is made at runtime. Abort program startup if the initial neighbor configuration contains errors. Related: OS#5018 Change-Id: I9ed992f8bfff888b3933733c0576f92d50f2625b
Diffstat (limited to 'src/osmo-bsc/handover_decision_2.c')
-rw-r--r--src/osmo-bsc/handover_decision_2.c39
1 files changed, 19 insertions, 20 deletions
diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c
index 0d0391cc2..b397a9ac5 100644
--- a/src/osmo-bsc/handover_decision_2.c
+++ b/src/osmo-bsc/handover_decision_2.c
@@ -83,8 +83,8 @@
#define LOGPHOCAND(candidate, level, fmt, args...) do {\
if ((candidate)->target.bts) \
LOGPHOLCHANTOBTS((candidate)->current.lchan, (candidate)->target.bts, level, fmt, ## args); \
- else if ((candidate)->target.cil) \
- LOGPHOLCHANTOREMOTE((candidate)->current.lchan, (candidate)->target.cil, level, fmt, ## args); \
+ else if ((candidate)->target.cell_ids.id_list_len) \
+ LOGPHOLCHANTOREMOTE((candidate)->current.lchan, &(candidate)->target.cell_ids, level, fmt, ## args); \
} while(0)
@@ -120,8 +120,8 @@ struct ho_candidate {
int lchan_frees_tchh;
} current;
struct {
- struct neighbor_ident_key nik; /* neighbor ARFCN+BSIC */
- const struct gsm0808_cell_id_list2 *cil; /* target cells in remote BSS */
+ struct cell_ab ab; /* neighbor ARFCN+BSIC */
+ struct gsm0808_cell_id_list2 cell_ids; /* target cells in remote BSS */
struct gsm_bts *bts;
int rxlev;
int rxlev_afs_bias;
@@ -747,9 +747,9 @@ static void check_requirements_remote_bss(struct ho_candidate *c)
/* Requirement A */
/* the handover penalty timer must not run for this bts */
- penalty_time = penalty_timers_remaining_list(&c->current.lchan->conn->hodec2.penalty_timers, c->target.cil);
+ penalty_time = penalty_timers_remaining_list(&c->current.lchan->conn->hodec2.penalty_timers, &c->target.cell_ids);
if (penalty_time) {
- LOGPHOLCHANTOREMOTE(c->current.lchan, c->target.cil, LOGL_DEBUG,
+ LOGPHOLCHANTOREMOTE(c->current.lchan, &c->target.cell_ids, LOGL_DEBUG,
"not a candidate, target BSS still in penalty time"
" (%u seconds left)\n", penalty_time);
return;
@@ -879,9 +879,9 @@ static int trigger_local_ho_or_as(struct ho_candidate *c, uint8_t requirements)
req = (struct handover_out_req){
.from_hodec_id = HODEC2,
.old_lchan = c->current.lchan,
- .target_nik = *bts_ident_key(c->target.bts),
.new_lchan_type = full_rate? GSM_LCHAN_TCH_F : GSM_LCHAN_TCH_H,
};
+ bts_cell_ab(&req.target_cell_ab, c->target.bts);
handover_request(&req);
return 0;
}
@@ -890,14 +890,14 @@ static int trigger_remote_bss_ho(struct ho_candidate *c, uint8_t requirements)
{
struct handover_out_req req;
- LOGPHOLCHANTOREMOTE(c->current.lchan, c->target.cil, LOGL_INFO,
+ LOGPHOLCHANTOREMOTE(c->current.lchan, &c->target.cell_ids, LOGL_INFO,
"Triggering inter-BSC handover, due to %s\n",
ho_reason_name(global_ho_reason));
req = (struct handover_out_req){
.from_hodec_id = HODEC2,
.old_lchan = c->current.lchan,
- .target_nik = c->target.nik,
+ .target_cell_ab = c->target.ab,
};
handover_request(&req);
return 0;
@@ -933,13 +933,13 @@ static inline void debug_candidate(struct ho_candidate *candidate)
candidate->target.free_tch##tchx, candidate->target.min_free_tch##tchx, \
REQUIREMENTS_ARGS(candidate->requirements, TCHX)
- if (!candidate->target.bts && !candidate->target.cil)
+ if (!candidate->target.bts && !candidate->target.cell_ids.id_list_len)
LOGPHOLCHAN(candidate->current.lchan, LOGL_DEBUG, "Empty candidate\n");
- if (candidate->target.bts && candidate->target.cil)
+ if (candidate->target.bts && candidate->target.cell_ids.id_list_len)
LOGPHOLCHAN(candidate->current.lchan, LOGL_ERROR, "Invalid candidate: both local- and remote-BSS target\n");
- if (candidate->target.cil)
- LOGPHOLCHANTOREMOTE(candidate->current.lchan, candidate->target.cil, LOGL_DEBUG,
+ if (candidate->target.cell_ids.id_list_len)
+ LOGPHOLCHANTOREMOTE(candidate->current.lchan, &candidate->target.cell_ids, LOGL_DEBUG,
"RX level %d dBm -> %d dBm\n",
rxlev2dbm(candidate->current.rxlev), rxlev2dbm(candidate->target.rxlev));
@@ -1052,9 +1052,8 @@ static void collect_handover_candidate(struct gsm_lchan *lchan, struct neigh_mea
{
struct gsm_bts *bts = lchan->ts->trx->bts;
struct gsm_bts *neighbor_bts;
- const struct gsm0808_cell_id_list2 *neighbor_cil;
- struct neighbor_ident_key ni = {
- .from_bts = bts->nr,
+ struct gsm0808_cell_id_list2 neighbor_cil;
+ struct cell_ab target_ab = {
.arfcn = nmp->arfcn,
.bsic = nmp->bsic,
};
@@ -1078,9 +1077,9 @@ static void collect_handover_candidate(struct gsm_lchan *lchan, struct neigh_mea
}
find_handover_target_cell(&neighbor_bts, &neighbor_cil,
- lchan->conn, &ni, false);
+ lchan->conn, &target_ab, false);
- if (!neighbor_bts && !neighbor_cil) {
+ if (!neighbor_bts && !neighbor_cil.id_list_len) {
LOGPHOBTS(bts, LOGL_DEBUG, "no neighbor ARFCN %u BSIC %u configured for this cell\n",
nmp->arfcn, nmp->bsic);
return;
@@ -1103,9 +1102,9 @@ static void collect_handover_candidate(struct gsm_lchan *lchan, struct neigh_mea
.rxlev = rxlev_current,
},
.target = {
- .nik = ni,
+ .ab = target_ab,
.bts = neighbor_bts,
- .cil = neighbor_cil,
+ .cell_ids = neighbor_cil,
.rxlev = neigh_meas_avg(nmp, ho_get_hodec2_rxlev_neigh_avg_win(bts->ho)),
},
};