[PATCH] bsc/mminfo: Patch timezone and DST in MM Info messages

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/.

Jacob Erlbeck jerlbeck at sysmocom.de
Mon Sep 16 12:50:14 UTC 2013


This adds in-place patching of the time information in the
MM INFORMATION message. The timezone in the 'Local time zone' and
the 'Universal time and local time zone' information elements
and the offset in the 'Network Daylight Saving Time' information
element are optionally set.

The new values are determined by the 'timezone' vty command in the
config_net_bts node. That command is extended by an optional
DST offset parameter.

Ticket: OW#978
---
 openbsc/include/openbsc/gsm_data_shared.h |    1 +
 openbsc/src/libbsc/bsc_vty.c              |   37 +++++++++++++++++-
 openbsc/src/osmo-bsc/osmo_bsc_filter.c    |   58 ++++++++++++++++++++++++++++-
 openbsc/tests/vty_test_runner.py          |   34 +++++++++++++++++
 4 files changed, 127 insertions(+), 3 deletions(-)

diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index 3ef1457..437378a 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -594,6 +594,7 @@ struct gsm_bts {
 		int hr;
 		int mn;
 		int override;
+		int dst;
 	} tz;
 
 	/* ip.accesss Unit ID's have Site/BTS/TRX layout */
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 2cbcf44..7c0d998 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -489,8 +489,14 @@ static void config_write_bts_single(struct vty *vty, struct gsm_bts *bts)
 		VTY_NEWLINE);
 	vty_out(vty, "  training_sequence_code %u%s", bts->tsc, VTY_NEWLINE);
 	vty_out(vty, "  base_station_id_code %u%s", bts->bsic, VTY_NEWLINE);
-	if (bts->tz.override != 0)
-		vty_out(vty, "  timezone %d %d%s", bts->tz.hr, bts->tz.mn, VTY_NEWLINE);
+	if (bts->tz.override != 0) {
+		if (bts->tz.dst)
+			vty_out(vty, "  timezone %d %d %d%s",
+				bts->tz.hr, bts->tz.mn, bts->tz.dst, VTY_NEWLINE);
+		else
+			vty_out(vty, "  timezone %d %d%s",
+				bts->tz.hr, bts->tz.mn, VTY_NEWLINE);
+	}
 	vty_out(vty, "  ms max power %u%s", bts->ms_max_power, VTY_NEWLINE);
 	vty_out(vty, "  cell reselection hysteresis %u%s",
 		bts->si_common.cell_sel_par.cell_resel_hyst*2, VTY_NEWLINE);
@@ -1613,6 +1619,32 @@ DEFUN(cfg_bts_timezone,
 
 	bts->tz.hr = tzhr;
 	bts->tz.mn = tzmn;
+	bts->tz.dst = 0;
+	bts->tz.override = 1;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_timezone_dst,
+      cfg_bts_timezone_dst_cmd,
+      "timezone <-19-19> (0|15|30|45) <0-2>",
+      "Set the Timezone Offset of this BTS\n"
+      "Timezone offset (hours)\n"
+      "Timezone offset (00 minutes)\n"
+      "Timezone offset (15 minutes)\n"
+      "Timezone offset (30 minutes)\n"
+      "Timezone offset (45 minutes)\n"
+      "DST offset (hours)\n"
+      )
+{
+	struct gsm_bts *bts = vty->index;
+	int tzhr = atoi(argv[0]);
+	int tzmn = atoi(argv[1]);
+	int tzdst = atoi(argv[2]);
+
+	bts->tz.hr = tzhr;
+	bts->tz.mn = tzmn;
+	bts->tz.dst = tzdst;
 	bts->tz.override = 1;
 
 	return CMD_SUCCESS;
@@ -3064,6 +3096,7 @@ int bsc_vty_init(const struct log_info *cat)
 	install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
 	install_element(BTS_NODE, &cfg_bts_rsl_ip_cmd);
 	install_element(BTS_NODE, &cfg_bts_timezone_cmd);
+	install_element(BTS_NODE, &cfg_bts_timezone_dst_cmd);
 	install_element(BTS_NODE, &cfg_bts_no_timezone_cmd);
 	install_element(BTS_NODE, &cfg_bts_nokia_site_skip_reset_cmd);
 	install_element(BTS_NODE, &cfg_bts_stream_id_cmd);
diff --git a/openbsc/src/osmo-bsc/osmo_bsc_filter.c b/openbsc/src/osmo-bsc/osmo_bsc_filter.c
index 957ceaf..6b8313e 100644
--- a/openbsc/src/osmo-bsc/osmo_bsc_filter.c
+++ b/openbsc/src/osmo-bsc/osmo_bsc_filter.c
@@ -251,6 +251,57 @@ int bsc_send_welcome_ussd(struct gsm_subscriber_connection *conn)
 	return 0;
 }
 
+static int bsc_patch_mm_info(struct gsm_subscriber_connection *conn,
+		uint8_t *data, unsigned int length)
+{
+	struct tlv_parsed tp;
+	int parse_res;
+	struct gsm_bts *bts = conn->bts;
+
+	parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, data, length, 0, 0);
+	if (parse_res <= 0 && parse_res != -3)
+		return 0;
+
+	if (bts->tz.override) {
+		/* TZ patching is enabled */
+		int tzunits;
+		uint8_t tzbsd = 0;
+		uint8_t dst = 0;
+
+		/* Convert tz.hr and tz.mn to units */
+		if (bts->tz.hr < 0) {
+			tzunits = -bts->tz.hr*4;
+			tzbsd |= 0x08;
+		} else
+			tzunits = bts->tz.hr*4;
+
+		tzunits = tzunits + (bts->tz.mn/15);
+
+		tzbsd |= (tzunits % 10)*0x10 + (tzunits / 10);
+
+		/* Convert DST value */
+		if (bts->tz.dst >= 0 && bts->tz.dst <= 2)
+			dst = bts->tz.dst;
+
+		if (TLVP_PRESENT(&tp, GSM48_IE_UTC)) {
+			LOGP(DMSC, LOGL_DEBUG, "Changing 'Local time zone' from 0x%02x to 0x%02x.\n", TLVP_VAL(&tp, GSM48_IE_UTC)[6], tzbsd);
+			((uint8_t *)(TLVP_VAL(&tp, GSM48_IE_UTC)))[0] = tzbsd;
+		}
+		if (TLVP_PRESENT(&tp, GSM48_IE_NET_TIME_TZ)) {
+			LOGP(DMSC, LOGL_DEBUG, "Changing 'Universal time and local time zone' TZ from 0x%02x to 0x%02x.\n", TLVP_VAL(&tp, GSM48_IE_NET_TIME_TZ)[6], tzbsd);
+			((uint8_t *)(TLVP_VAL(&tp, GSM48_IE_NET_TIME_TZ)))[6] = tzbsd;
+		}
+#ifdef GSM48_IE_NET_DST
+		if (TLVP_PRESENT(&tp, GSM48_IE_NET_DST)) {
+			LOGP(DMSC, LOGL_DEBUG, "Changing 'Network daylight saving time' from 0x%02x to 0x%02x.\n", TLVP_VAL(&tp, GSM48_IE_NET_DST)[0], dst);
+			((uint8_t *)(TLVP_VAL(&tp, GSM48_IE_NET_DST)))[0] = dst;
+		}
+#endif
+	}
+
+	return 0;
+}
+
 /**
  * Messages coming back from the MSC.
  */
@@ -261,13 +312,16 @@ int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
 	struct gsm48_loc_area_id *lai;
 	struct gsm48_hdr *gh;
 	uint8_t mtype;
+	int length = msgb_l3len(msg);
 
-	if (msgb_l3len(msg) < sizeof(*gh)) {
+	if (length < sizeof(*gh)) {
 		LOGP(DMSC, LOGL_ERROR, "GSM48 header does not fit.\n");
 		return -1;
 	}
 
 	gh = (struct gsm48_hdr *) msgb_l3(msg);
+	length -= (const char *)&gh->data[0] - (const char *)gh;
+
 	mtype = gh->msg_type & 0xbf;
 	net = conn->bts->network;
 	msc = conn->sccp_con->msc;
@@ -285,6 +339,8 @@ int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
 		if (conn->sccp_con->new_subscriber)
 			return send_welcome_ussd(conn);
 		return 0;
+	} else if (mtype == GSM48_MT_MM_INFO) {
+		bsc_patch_mm_info(conn, &gh->data[0], length);
 	}
 
 	return 0;
diff --git a/openbsc/tests/vty_test_runner.py b/openbsc/tests/vty_test_runner.py
index 7f71288..c0ba57d 100644
--- a/openbsc/tests/vty_test_runner.py
+++ b/openbsc/tests/vty_test_runner.py
@@ -280,6 +280,40 @@ class TestVTYBSC(TestVTYGenericBSC):
         self.assertEquals(res.find('missing-msc-text No MSC found'), -1)
         self.assert_(res.find('no missing-msc-text') > 0)
 
+    def testNetworkTimezone(self):
+        self.vty.enable()
+        self.vty.verify("configure terminal", [''])
+        self.vty.verify("network", [''])
+        self.vty.verify("bts 0", [''])
+
+        # Test invalid input
+        self.vty.verify("timezone", ['% Command incomplete.'])
+        self.vty.verify("timezone 20 0", ['% Unknown command.'])
+        self.vty.verify("timezone 0 11", ['% Unknown command.'])
+        self.vty.verify("timezone 0 0 99", ['% Unknown command.'])
+
+        # Set time zone without DST
+        self.vty.verify("timezone 2 30", [''])
+
+        # Verify settings
+        res = self.vty.command("write terminal")
+        self.assert_(res.find('timezone 2 30') > 0)
+        self.assertEquals(res.find('timezone 2 30 '), -1)
+
+        # Set time zone with DST
+        self.vty.verify("timezone 2 30 1", [''])
+
+        # Verify settings
+        res = self.vty.command("write terminal")
+        self.assert_(res.find('timezone 2 30 1') > 0)
+
+        # Now disable it..
+        self.vty.verify("no timezone", [''])
+
+        # Verify settings
+        res = self.vty.command("write terminal")
+        self.assertEquals(res.find(' timezone'), -1)
+
 class TestVTYNAT(TestVTYGenericBSC):
 
     def vty_command(self):
-- 
1.7.9.5





More information about the OpenBSC mailing list