aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);
}