[osmo-bts,2/2] oml: Allow to send ACK/NACK message through a different socket.
diff mbox

Message ID 1400602882-24801-1-git-send-email-anayuso@sysmocom.de
State Changes Requested
Headers show

Commit Message

Alvaro Neira May 20, 2014, 4:21 p.m. UTC
From: Álvaro Neira Ayuso <anayuso@sysmocom.de>

This patch, I have done something for reach my goal. I have
changed the function oml_fom_ack_nack for returning the ACK/NACK
message that we have created. Later I have splited the function
send_oml_msg in two different function. One for send the oml
messages with abis (send_oml_msg) and another for append the
fom header in the message. Before of that we always add the fom
before of send the message with Abis always.

Later I have modified the code for using the new functions.

Signed-off-by: Alvaro Neira Ayuso <anayuso@sysmocom.de>
---
 include/osmo-bts/oml.h   |    4 +-
 src/common/oml.c         |  103 ++++++++++++++++++++++++++++++----------------
 src/osmo-bts-sysmo/oml.c |    2 +-
 3 files changed, 70 insertions(+), 39 deletions(-)

Patch
diff mbox

diff --git a/include/osmo-bts/oml.h b/include/osmo-bts/oml.h
index 4281fd3..1e697d6 100644
--- a/include/osmo-bts/oml.h
+++ b/include/osmo-bts/oml.h
@@ -5,7 +5,7 @@  int oml_init(void);
 int down_oml(struct gsm_bts *bts, struct msgb *msg);
 
 struct msgb *oml_msgb_alloc(void);
-int oml_send_msg(struct msgb *msg, int is_mauf);
+int oml_send_msg(struct msgb *msg);
 int oml_mo_send_msg(struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_type);
 int oml_mo_opstart_ack(struct gsm_abis_mo *mo);
 int oml_mo_opstart_nack(struct gsm_abis_mo *mo, uint8_t nack_cause);
@@ -27,7 +27,7 @@  int oml_tx_state_changed(struct gsm_abis_mo *mo);
 
 int oml_mo_tx_sw_act_rep(struct gsm_abis_mo *mo);
 
-int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause);
+struct msgb *oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause);
 
 int oml_mo_fom_ack_nack(struct gsm_abis_mo *mo, uint8_t orig_msg_type,
 			uint8_t cause);
diff --git a/src/common/oml.c b/src/common/oml.c
index 42e4e80..ba3323b 100644
--- a/src/common/oml.c
+++ b/src/common/oml.c
@@ -160,7 +160,7 @@  struct msgb *oml_msgb_alloc(void)
 	return msgb_alloc_headroom(1024, 128, "OML");
 }
 
-int oml_send_msg(struct msgb *msg, int is_manuf)
+void oml_append_fom_hdr(struct msgb *msg, int is_manuf)
 {
 	struct abis_om_hdr *omh;
 
@@ -175,7 +175,10 @@  int oml_send_msg(struct msgb *msg, int is_manuf)
 	omh->length = msgb_l3len(msg);
 
 	msg->l2h = (uint8_t *)omh;
+}
 
+int oml_send_msg(struct msgb *msg)
+{
 	return abis_oml_sendmsg(msg);
 }
 
@@ -192,7 +195,9 @@  int oml_mo_send_msg(struct gsm_abis_mo *mo, struct msgb *msg, uint8_t msg_type)
 	/* FIXME: This assumption may not always be correct */
 	msg->trx = mo->bts->c0;
 
-	return oml_send_msg(msg, 0);
+	oml_append_fom_hdr(msg, 0);
+
+	return oml_send_msg(msg);
 }
 
 /* FIXME: move to gsm_data_shared */
@@ -308,7 +313,7 @@  int oml_mo_opstart_nack(struct gsm_abis_mo *mo, uint8_t nack_cause)
 	return oml_mo_fom_ack_nack(mo, NM_MT_OPSTART, nack_cause);
 }
 
-int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause)
+struct msgb *oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause)
 {
 	struct abis_om_hdr *old_oh = msgb_l2(old_msg);
 	struct abis_om_fom_hdr *old_foh = msgb_l3(old_msg);
@@ -318,8 +323,10 @@  int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause)
 	uint8_t *manuf;
 
 	msg = oml_msgb_alloc();
-	if (!msg)
-		return -ENOMEM;
+	if (!msg) {
+		LOGP(DOML, LOGL_ERROR, "Creating oml ACK/NACK msg.\n");
+		return NULL;
+	}
 
 	/* make sure to respond with MANUF if request was MANUF */
 	if (old_oh->mdisc == ABIS_OM_MDISC_MANUF)
@@ -357,12 +364,15 @@  int oml_fom_ack_nack(struct msgb *old_msg, uint8_t cause)
 			manuf[0] = sizeof(ipaccess_magic);
 			memcpy(manuf+1, ipaccess_magic, sizeof(ipaccess_magic));
 		} else {
+			msgb_free(msg);
 			LOGP(DOML, LOGL_ERROR, "Unknown manufacturer label.\n");
-			return -1;
+			return NULL;
 		}
 	}
 
-	return oml_send_msg(msg, is_manuf);
+	oml_append_fom_hdr(msg, is_manuf);
+
+	return msg;
 }
 
 /*
@@ -420,7 +430,8 @@  static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
 
 	rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
 	if (rc < 0)
-		return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_INCORR_STRUCT));
 
 	/* Test for globally unsupported stuff here */
 	if (TLVP_PRESENT(&tp, NM_ATT_BCCH_ARFCN)) {
@@ -433,12 +444,14 @@  static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
 
 		if (arfcn > 1024) {
 			LOGP(DOML, LOGL_NOTICE, "Given ARFCN %d is not supported.\n", arfcn);
-			return oml_fom_ack_nack(msg, NM_NACK_FREQ_NOTAVAIL);
+			return oml_send_msg(oml_fom_ack_nack(msg,
+							NM_NACK_FREQ_NOTAVAIL));
 		}
 	}
 	/* 9.4.52 Starting Time */
 	if (TLVP_PRESENT(&tp, NM_ATT_START_TIME)) {
-		return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						    NM_NACK_SPEC_IMPL_NOTSUPP));
 	}
 
 	/* merge existing BTS attributes with new attributes */
@@ -449,7 +462,7 @@  static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
 	rc = bts_model_check_oml(bts, foh->msg_type, bts->mo.nm_attr, tp_merged, bts);
 	if (rc < 0) {
 		talloc_free(tp_merged);
-		return oml_fom_ack_nack(msg, -rc);
+		return oml_send_msg(oml_fom_ack_nack(msg, -rc));
 	}
 
 	/* Success: replace old BTS attributes with new */
@@ -479,7 +492,8 @@  static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
 			LOGP(DOML, LOGL_NOTICE, "Given Conn. Failure Criterion "
 				"not supported. Please use critetion 0x01 with "
 				"RADIO_LINK_TIMEOUT value of 4..64\n");
-			return oml_fom_ack_nack(msg, NM_NACK_PARAM_RANGE);
+			return oml_send_msg(oml_fom_ack_nack(msg,
+							  NM_NACK_PARAM_RANGE));
 		}
 		btsb->radio_link_timeout = val[1];
 	}
@@ -527,7 +541,8 @@  static int oml_rx_set_bts_attr(struct gsm_bts *bts, struct msgb *msg)
 		if (t3105 == 0) {
 			LOGP(DOML, LOGL_NOTICE,
 				"T3105 must have a value != 0.\n");
-			return oml_fom_ack_nack(msg, NM_NACK_PARAM_RANGE);
+			return oml_send_msg(oml_fom_ack_nack(msg,
+							  NM_NACK_PARAM_RANGE));
 		}
 		btsb->t3105_ms = t3105 * 10;
 	}
@@ -560,7 +575,8 @@  static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg)
 
 	rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
 	if (rc < 0)
-		return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_INCORR_STRUCT));
 
 	/* merge existing BTS attributes with new attributes */
 	tp_merged = tlvp_copy(trx->mo.nm_attr, trx->bts);
@@ -570,7 +586,7 @@  static int oml_rx_set_radio_attr(struct gsm_bts_trx *trx, struct msgb *msg)
 	rc = bts_model_check_oml(trx->bts, foh->msg_type, trx->mo.nm_attr, tp_merged, trx);
 	if (rc < 0) {
 		talloc_free(tp_merged);
-		return oml_fom_ack_nack(msg, -rc);
+		return oml_send_msg(oml_fom_ack_nack(msg, -rc));
 	}
 
 	/* Success: replace old BTS attributes with new */
@@ -666,19 +682,22 @@  static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg)
 
 	rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
 	if (rc < 0)
-		return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_INCORR_STRUCT));
 
 	/* 9.4.21 HSN... */
 	/* 9.4.27 MAIO */
 	if (TLVP_PRESENT(&tp, NM_ATT_HSN) || TLVP_PRESENT(&tp, NM_ATT_MAIO)) {
 		LOGP(DOML, LOGL_NOTICE, "SET CHAN ATTR: Frequency hopping not supported.\n");
-		return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						    NM_NACK_SPEC_IMPL_NOTSUPP));
 	}
 
 	/* 9.4.52 Starting Time */
 	if (TLVP_PRESENT(&tp, NM_ATT_START_TIME)) {
 		LOGP(DOML, LOGL_NOTICE, "SET CHAN ATTR: Starting time not supported.\n");
-		return oml_fom_ack_nack(msg, NM_NACK_SPEC_IMPL_NOTSUPP);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						    NM_NACK_SPEC_IMPL_NOTSUPP));
 	}
 
 	/* merge existing BTS attributes with new attributes */
@@ -690,7 +709,7 @@  static int oml_rx_set_chan_attr(struct gsm_bts_trx_ts *ts, struct msgb *msg)
 	if (rc < 0) {
 		talloc_free(tp_merged);
 		/* Send NACK */
-		return oml_fom_ack_nack(msg, -rc);
+		return oml_send_msg(oml_fom_ack_nack(msg, -rc));
 	}
 
 	/* Success: replace old BTS attributes with new */
@@ -734,7 +753,8 @@  static int oml_rx_opstart(struct gsm_bts *bts, struct msgb *msg)
 	mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
 	obj = gsm_objclass2obj(bts, foh->obj_class, &foh->obj_inst);
 	if (!mo || !obj)
-		return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_OBJINST_UNKN));
 
 	/* Step 2: Do some global dependency/consistency checking */
 	if (mo->nm_state.operational == NM_OPSTATE_ENABLED) {
@@ -761,12 +781,14 @@  static int oml_rx_chg_adm_state(struct gsm_bts *bts, struct msgb *msg)
 	rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
 	if (rc < 0) {
 		LOGP(DOML, LOGL_ERROR, "Rx CHG ADM STATE: error during TLV parse\n");
-		return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_INCORR_STRUCT));
 	}
 
 	if (!TLVP_PRESENT(&tp, NM_ATT_ADM_STATE)) {
 		LOGP(DOML, LOGL_ERROR, "Rx CHG ADM STATE: no ADM state attribute\n");
-		return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_INCORR_STRUCT));
 	}
 
 	adm_state = *TLVP_VAL(&tp, NM_ATT_ADM_STATE);
@@ -775,7 +797,8 @@  static int oml_rx_chg_adm_state(struct gsm_bts *bts, struct msgb *msg)
 	mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
 	obj = gsm_objclass2obj(bts, foh->obj_class, &foh->obj_inst);
 	if (!mo || !obj)
-		return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_OBJINST_UNKN));
 
 	/* Step 2: Do some global dependency/consistency checking */
 	if (mo->nm_state.administrative == adm_state)
@@ -800,7 +823,7 @@  static int down_fom(struct gsm_bts *bts, struct msgb *msg)
 
 	if (foh->obj_inst.bts_nr != 0 && foh->obj_inst.bts_nr != 0xff) {
 		LOGP(DOML, LOGL_INFO, "Formatted O&M with BTS %d out of range.\n", foh->obj_inst.bts_nr);
-		return oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN);
+		return oml_send_msg(oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN));
 	}
 
 	switch (foh->msg_type) {
@@ -810,15 +833,18 @@  static int down_fom(struct gsm_bts *bts, struct msgb *msg)
 	case NM_MT_SET_RADIO_ATTR:
 		trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
 		if (!trx)
-			return oml_fom_ack_nack(msg, NM_NACK_TRXNR_UNKN);
+			return oml_send_msg(oml_fom_ack_nack(msg,
+							   NM_NACK_TRXNR_UNKN));
 		ret = oml_rx_set_radio_attr(trx, msg);
 		break;
 	case NM_MT_SET_CHAN_ATTR:
 		trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);
 		if (!trx)
-			return oml_fom_ack_nack(msg, NM_NACK_TRXNR_UNKN);
+			return oml_send_msg(oml_fom_ack_nack(msg,
+							   NM_NACK_TRXNR_UNKN));
 		if (foh->obj_inst.ts_nr >= ARRAY_SIZE(trx->ts))
-			return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN);
+			return oml_send_msg(oml_fom_ack_nack(msg,
+							 NM_NACK_OBJINST_UNKN));
 		ret = oml_rx_set_chan_attr(&trx->ts[foh->obj_inst.ts_nr], msg);
 		break;
 	case NM_MT_OPSTART:
@@ -833,7 +859,8 @@  static int down_fom(struct gsm_bts *bts, struct msgb *msg)
 	default:
 		LOGP(DOML, LOGL_INFO, "unknown Formatted O&M msg_type 0x%02x\n",
 			foh->msg_type);
-		ret = oml_fom_ack_nack(msg, NM_NACK_MSGTYPE_INVAL);
+		ret = oml_send_msg(oml_fom_ack_nack(msg,
+						    NM_NACK_MSGTYPE_INVAL));
 	}
 
 	return ret;
@@ -1000,17 +1027,19 @@  static int oml_ipa_set_attr(struct gsm_bts *bts, struct msgb *msg)
 
 	rc = oml_tlv_parse(&tp, foh->data, msgb_l3len(msg) - sizeof(*foh));
 	if (rc < 0)
-		return oml_fom_ack_nack(msg, NM_NACK_INCORR_STRUCT);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_INCORR_STRUCT));
 
 	/* Resolve MO by obj_class/obj_inst */
 	mo = gsm_objclass2mo(bts, foh->obj_class, &foh->obj_inst);
 	obj = gsm_objclass2obj(bts, foh->obj_class, &foh->obj_inst);
 	if (!mo || !obj)
-		return oml_fom_ack_nack(msg, NM_NACK_OBJINST_UNKN);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_OBJINST_UNKN));
 
 	rc = oml_ipa_mo_set_attr(bts, mo, obj, &tp);
 
-	return oml_fom_ack_nack(msg, rc);
+	return oml_send_msg(oml_fom_ack_nack(msg, rc));
 }
 
 static int rx_oml_ipa_rsl_connect(struct gsm_bts_trx *trx, struct msgb *msg,
@@ -1041,10 +1070,11 @@  static int rx_oml_ipa_rsl_connect(struct gsm_bts_trx *trx, struct msgb *msg,
 	rc = e1inp_ipa_bts_rsl_connect(oml_link->ts->line, inet_ntoa(in), port);
 	if (rc < 0) {
 		LOGP(DOML, LOGL_ERROR, "Error in abis_open(RSL): %d\n", rc);
-		return oml_fom_ack_nack(msg, NM_NACK_CANT_PERFORM);
+		return oml_send_msg(oml_fom_ack_nack(msg,
+						     NM_NACK_CANT_PERFORM));
 	}
 
-	return oml_fom_ack_nack(msg, 0);
+	return oml_send_msg(oml_fom_ack_nack(msg, 0));
 }
 
 static int down_mom(struct gsm_bts *bts, struct msgb *msg)
@@ -1071,13 +1101,13 @@  static int down_mom(struct gsm_bts *bts, struct msgb *msg)
 
 	if (foh->obj_inst.bts_nr != 0 && foh->obj_inst.bts_nr != 0xff) {
 		LOGP(DOML, LOGL_INFO, "Manufacturer O&M with BTS %d out of range.\n", foh->obj_inst.bts_nr);
-		return oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN);
+		return oml_send_msg(oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN));
 	}
 
 	ret = oml_tlv_parse(&tp, foh->data, oh->length - sizeof(*foh));
 	if (ret < 0) {
 		LOGP(DOML, LOGL_ERROR, "TLV parse error %d\n", ret);
-		return oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN);
+		return oml_send_msg(oml_fom_ack_nack(msg, NM_NACK_BTSNR_UNKN));
 	}
 
 	abis_nm_debugp_foh(DOML, foh);
@@ -1094,7 +1124,8 @@  static int down_mom(struct gsm_bts *bts, struct msgb *msg)
 	default:
 		LOGP(DOML, LOGL_INFO, "Manufacturer Formatted O&M msg_type 0x%02x\n",
 			foh->msg_type);
-		ret = oml_fom_ack_nack(msg, NM_NACK_MSGTYPE_INVAL);
+		ret = oml_send_msg(oml_fom_ack_nack(msg,
+						    NM_NACK_MSGTYPE_INVAL));
 	}
 
 	return ret;
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c
index 4ebf664..a268294 100644
--- a/src/osmo-bts-sysmo/oml.c
+++ b/src/osmo-bts-sysmo/oml.c
@@ -1548,7 +1548,7 @@  int bts_model_apply_oml(struct gsm_bts *bts, struct msgb *msg,
 	}
 
 	/* FIXME: we actaully need to send a ACK or NACK for the OML message */
-	return oml_fom_ack_nack(msg, 0);
+	return oml_send_msg(oml_fom_ack_nack(msg, 0));
 }
 
 /* callback from OML */