[PATCH 4/4] abis_nm: Fix ACTIVATE SW parameters

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Sylvain Munaut 246tnt at gmail.com
Sun Oct 25 16:56:44 UTC 2009


From: Sylvain Munaut <tnt at 246tNt.com>

The previous code only sent the FILE_ID tag data part,
but according to the GSM 12.21 spec, section 8.3.6, the
full SW Description 'object' must be sent so that includes
the NM_ATT_SW_DESCR tag, the whole FILE_ID and the whole
FILE_VERSION (including tags & length fields).

Note that functionnaly on a nanoBTS 139 I couldn't see any
difference ... whatever I send in there it works ...

Signed-off-by: Sylvain Munaut <tnt at 246tNt.com>
---
 openbsc/src/abis_nm.c |   61 +++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 49 insertions(+), 12 deletions(-)

diff --git a/openbsc/src/abis_nm.c b/openbsc/src/abis_nm.c
index 03d9def..c2641c4 100755
--- a/openbsc/src/abis_nm.c
+++ b/openbsc/src/abis_nm.c
@@ -878,16 +878,57 @@ static int ipacc_sw_activate(struct gsm_bts *bts, u_int8_t obj_class, u_int8_t i
 	return abis_nm_sendmsg(bts, msg);
 }
 
+static int abis_nm_parse_sw_descr(const u_int8_t *sw_descr, int sw_descr_len)
+{
+	static const struct tlv_definition sw_descr_def = {
+		.def = {
+			[NM_ATT_FILE_ID] =		{ TLV_TYPE_TL16V, },
+			[NM_ATT_FILE_VERSION] =		{ TLV_TYPE_TL16V, },
+		},
+	};
+
+	u_int8_t tag;
+	u_int16_t tag_len;
+	const u_int8_t *val;
+	int ofs = 0, len;
+
+	/* Classic TLV parsing doesn't work well with SW_DESCR because of it's
+	 * nested nature and the fact you have to assume it contains only two sub
+	 * tags NM_ATT_FILE_VERSION & NM_ATT_FILE_ID to parse it */
+
+	if (sw_descr[0] != NM_ATT_SW_DESCR) {
+		DEBUGP(DNM, "SW_DESCR attribute identifier not found!\n");
+		return -1;
+	}
+	ofs += 1;
+
+	len = tlv_parse_one(&tag, &tag_len, &val,
+		&sw_descr_def, &sw_descr[ofs], sw_descr_len-ofs);
+	if (len < 0 || (tag != NM_ATT_FILE_ID)) {
+		DEBUGP(DNM, "FILE_ID attribute identifier not found!\n");
+		return -2;
+	}
+	ofs += len;
+
+	len = tlv_parse_one(&tag, &tag_len, &val,
+		&sw_descr_def, &sw_descr[ofs], sw_descr_len-ofs);
+	if (len < 0 || (tag != NM_ATT_FILE_VERSION)) {
+		DEBUGP(DNM, "FILE_VERSION attribute identifier not found!\n");
+		return -3;
+	}
+	ofs += len;
+
+	return ofs;
+}
+
 static int abis_nm_rx_sw_act_req(struct msgb *mb)
 {
 	struct abis_om_hdr *oh = msgb_l2(mb);
 	struct abis_om_fom_hdr *foh = msgb_l3(mb);
 	struct tlv_parsed tp;
 	const u_int8_t *sw_config;
-	int sw_config_len;
-	int file_id_len;
 	int nack = 0;
-	int ret;
+	int ret, sw_config_len, sw_descr_len;
 
 	debugp_foh(foh);
 
@@ -918,20 +959,16 @@ static int abis_nm_rx_sw_act_req(struct msgb *mb)
 		DEBUGP(DNM, "Found SW config: %s\n", hexdump(sw_config, sw_config_len));
 	}
 
-	if (sw_config[0] != NM_ATT_SW_DESCR)
-		DEBUGP(DNM, "SW_DESCR attribute identifier not found!\n");
-	if (sw_config[1] != NM_ATT_FILE_ID)
-		DEBUGP(DNM, "FILE_ID attribute identifier not found!\n");
-	file_id_len = sw_config[2] * 256 + sw_config[3];
+		/* Use the first SW_DESCR present in SW config */
+	sw_descr_len = abis_nm_parse_sw_descr(sw_config, sw_config_len);
+	if (sw_descr_len < 0)
+		return -EINVAL;
 
-	/* Assumes first SW file in list is the one to be activated */
-	/* sw_config + 4 to skip over 2 attribute ID bytes and 16-bit length field */
 	return ipacc_sw_activate(mb->trx->bts, foh->obj_class,
 				 foh->obj_inst.bts_nr,
 				 foh->obj_inst.trx_nr,
 				 foh->obj_inst.ts_nr,
-				 sw_config + 4,
-				 file_id_len);
+				 sw_config, sw_descr_len);
 }
 
 /* Receive a CHANGE_ADM_STATE_ACK, parse the TLV and update local state */
-- 
1.6.4





More information about the OpenBSC mailing list