OML: Ensure minimum required attributes are set before accepting OPSTART

There are some vital configuration bits such as ARFCN, BSIC, channel
config, .. for which there are no reasonable defaults.  As a result,
the BSC must set those attributes before issuing OPSTART.

Prior to this patch we would blindly accept OPSTART and then transmit
on ARFCN 0, which is definitely not the intended behavior.

Closes: OS#3789
Change-Id: I3a818f8eceb6abef1b20d2b3892a749dbc9e4b05
This commit is contained in:
Harald Welte 2019-02-09 23:00:40 +01:00
parent de3262fd27
commit a240bdd0a4
1 changed files with 53 additions and 1 deletions

View File

@ -993,6 +993,54 @@ static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg)
return bts_model_apply_oml(bts, msg, tp_merged, NM_OC_CHANNEL, ts);
}
/* return a list of mandatory attributes for given object class */
static unsigned int get_mand_attr_for_obj_class(uint8_t obj_class, const uint8_t **attr)
{
static const uint8_t bts_mand_attr[] = { NM_ATT_BCCH_ARFCN, NM_ATT_BSIC };
static const uint8_t trx_mand_attr[] = { NM_ATT_ARFCN_LIST, NM_ATT_RF_MAXPOWR_R };
static const uint8_t ts_mand_attr[] = { NM_ATT_CHAN_COMB };
static const uint8_t nse_mand_attr[] = { NM_ATT_IPACC_NSEI };
static const uint8_t cell_mand_attr[] = { NM_ATT_IPACC_BVCI, NM_ATT_IPACC_RAC };
static const uint8_t nsvc_mand_attr[] = { NM_ATT_IPACC_NSVCI, NM_ATT_IPACC_NS_LINK_CFG };
switch (obj_class) {
case NM_OC_BTS:
*attr = bts_mand_attr;
return sizeof(bts_mand_attr);
case NM_OC_RADIO_CARRIER:
*attr = trx_mand_attr;
return sizeof(trx_mand_attr);
case NM_OC_CHANNEL:
*attr = ts_mand_attr;
return sizeof(ts_mand_attr);
case NM_OC_GPRS_NSE:
*attr = nse_mand_attr;
return sizeof(nse_mand_attr);
case NM_OC_GPRS_CELL:
*attr = cell_mand_attr;
return sizeof(cell_mand_attr);
case NM_OC_GPRS_NSVC:
*attr = nsvc_mand_attr;
return sizeof(nsvc_mand_attr);
default:
return 0;
}
}
/* Verify if a given OML MO has the minimal attributes set to enable it */
static bool oml_mo_has_minimal_attributes(const struct gsm_abis_mo *mo)
{
unsigned int i;
const uint8_t *mand_attr = NULL;
unsigned int num_mand_attr = get_mand_attr_for_obj_class(mo->obj_class, &mand_attr);
for (i = 0; i < num_mand_attr; i++) {
if (!mo->nm_attr || !TLVP_PRESENT(mo->nm_attr, mand_attr[i]))
return false;
}
return true;
}
/* 8.9.2 Opstart has been received */
static int oml_rx_opstart(struct gsm_bts *bts, struct msgb *msg)
{
@ -1015,7 +1063,11 @@ static int oml_rx_opstart(struct gsm_bts *bts, struct msgb *msg)
return oml_mo_opstart_ack(mo);
}
/* Step 3: Ask BTS driver to apply the opstart */
/* Step 3: Check if all mandatory minimum attributes have been set */
if (!oml_mo_has_minimal_attributes(mo))
return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM);
/* Step 4: Ask BTS driver to apply the opstart */
return bts_model_opstart(bts, mo, obj);
}