osmo_bsc_main.c: verify the physical channel mapping at startup

As per 3GPP TS 45.002, section 3.3.2.3, and table 3 of clause 7,
the following limitations apply mapping of CCCH/BCCH channels:

  - TS0/C0 shall be configured as CCCH/BCCH (optionally combined);
  - combined CCCH (CCCH+SDCCH4) can only be used on TS0;
  - additional CCCHs can be on TS2, TS4, and TS6;
  - additional CCCHs are not allowed if TS0 is combined.

Let's make sure that OsmoBSC is properly configured before starring.

Change-Id: I758ef80f7884ba35cdf59d671ee30222ffb9d68b
This commit is contained in:
Vadim Yanitskiy 2019-11-02 00:57:23 +07:00
parent 9378522a0c
commit 73bd463061
3 changed files with 63 additions and 0 deletions

View File

@ -1749,4 +1749,6 @@ void gsm_trx_all_ts_dispatch(struct gsm_bts_trx *trx, uint32_t ts_ev, void *data
int bts_count_free_ts(struct gsm_bts *bts, enum gsm_phys_chan_config pchan);
bool trx_has_valid_pchan_config(const struct gsm_bts_trx *trx);
#endif /* _GSM_DATA_H */

View File

@ -1693,3 +1693,54 @@ const struct value_string lchan_activate_mode_names[] = {
OSMO_VALUE_STRING(FOR_VTY),
{}
};
bool trx_has_valid_pchan_config(const struct gsm_bts_trx *trx)
{
bool combined = false;
bool result = true;
unsigned int i;
/* Iterate over all timeslots */
for (i = 0; i < 8; i++) {
const struct gsm_bts_trx_ts *ts = &trx->ts[i];
switch (ts->pchan_from_config) {
case GSM_PCHAN_CCCH_SDCCH4_CBCH:
case GSM_PCHAN_CCCH_SDCCH4:
/* CCCH+SDCCH4 can only be configured on TS0 */
if (i > 0) {
LOGP(DNM, LOGL_ERROR, "Combined CCCH is not allowed "
"on TS%u > 0\n", i);
result = false;
}
if (i == 0)
combined = true;
/* fall-through */
case GSM_PCHAN_CCCH:
/* 3GPP TS 45.002, Table 3, CCCH: TS (0, 2, 4, 6) */
if (i % 2 != 0) {
LOGP(DNM, LOGL_ERROR, "%s is not allowed on odd TS%u\n",
gsm_pchan_name(ts->pchan_from_config), i);
result = false;
}
/* There can be no more CCCHs if TS0/C0 is combined */
if (i > 0 && combined) {
LOGP(DNM, LOGL_ERROR, "%s is not allowed on TS%u, "
"because TS0 is using combined channel configuration\n",
gsm_pchan_name(ts->pchan_from_config), i);
result = false;
}
break;
default:
/* CCCH on TS0 is mandatory for C0 */
if (trx->bts->c0 == trx && i == 0) {
LOGP(DNM, LOGL_ERROR, "TS0 on C0 must be CCCH/BCCH\n");
result = false;
}
}
}
return result;
}

View File

@ -401,6 +401,7 @@ static int inp_sig_cb(unsigned int subsys, unsigned int signal,
static int bootstrap_bts(struct gsm_bts *bts)
{
struct gsm_bts_trx *trx;
int i, n;
if (!bts->model)
@ -447,6 +448,15 @@ static int bootstrap_bts(struct gsm_bts *bts)
return -EINVAL;
}
/* Verify the physical channel mapping */
llist_for_each_entry(trx, &bts->trx_list, list) {
if (!trx_has_valid_pchan_config(trx)) {
LOGP(DNM, LOGL_ERROR, "TRX %u has invalid timeslot "
"configuration\n", trx->nr);
return -EINVAL;
}
}
/* Control Channel Description is set from vty/config */
/* Set ccch config by looking at ts config */