aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2019-02-09 23:00:40 +0100
committerHarald Welte <laforge@gnumonks.org>2019-02-23 15:59:18 +0100
commita240bdd0a4ea75cf748061d9b8cd8cfd8214e447 (patch)
treeec1a4b395ba078468275fb2837d77614cd87a8fa
parentde3262fd27624c4f6a7fb5c1b536931932a7e4db (diff)
OML: Ensure minimum required attributes are set before accepting OPSTARTlaforge/oml
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
-rw-r--r--src/common/oml.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/src/common/oml.c b/src/common/oml.c
index b04caf6..e95adba 100644
--- a/src/common/oml.c
+++ b/src/common/oml.c
@@ -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);
}