[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
Tue Sep 17 11:59:29 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.

Tests are provided for the vty part and for the plain
bsc_scan_msc_msg() function.

Ticket: OW#978
---
 openbsc/configure.ac                      |    4 +-
 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/Makefile.am                 |    4 +
 openbsc/tests/atlocal.in                  |    1 +
 openbsc/tests/bsc/Makefile.am             |   19 +++
 openbsc/tests/bsc/bsc_test.c              |  193 +++++++++++++++++++++++++++++
 openbsc/tests/bsc/bsc_test.ok             |    4 +
 openbsc/tests/testsuite.at                |    8 ++
 openbsc/tests/vty_test_runner.py          |   34 +++++
 11 files changed, 359 insertions(+), 4 deletions(-)
 create mode 100644 openbsc/tests/bsc/Makefile.am
 create mode 100644 openbsc/tests/bsc/bsc_test.c
 create mode 100644 openbsc/tests/bsc/bsc_test.ok

diff --git a/openbsc/configure.ac b/openbsc/configure.ac
index ce2a328..ddd15e3 100644
--- a/openbsc/configure.ac
+++ b/openbsc/configure.ac
@@ -36,11 +36,12 @@ AC_SUBST(osmo_ac_build_nat)
 
 # Enable/disable the BSC?
 AC_ARG_ENABLE([osmo-bsc], [AS_HELP_STRING([--enable-osmo-bsc], [Build the Osmo BSC])],
-    [osmo_ac_build_bsc="$enableval"])
+    [osmo_ac_build_bsc="$enableval"],[osmo_ac_build_bsc="no"])
 if test "$osmo_ac_build_bsc" = "yes" ; then
     PKG_CHECK_MODULES(LIBOSMOSCCP, libosmo-sccp >= 0.0.6)
 fi
 AM_CONDITIONAL(BUILD_BSC, test "x$osmo_ac_build_bsc" = "xyes")
+AC_SUBST(osmo_ac_build_bsc)
 
 # Enable/disable smpp support in the nitb?
 AC_ARG_ENABLE([smpp], [AS_HELP_STRING([--enable-smpp], [Build the SMPP interface])],
@@ -156,6 +157,7 @@ AC_OUTPUT(
     tests/gsm0408/Makefile
     tests/db/Makefile
     tests/channel/Makefile
+    tests/bsc/Makefile
     tests/bsc-nat/Makefile
     tests/bsc-nat-trie/Makefile
     tests/mgcp/Makefile
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/Makefile.am b/openbsc/tests/Makefile.am
index f2dc057..ed21fc3 100644
--- a/openbsc/tests/Makefile.am
+++ b/openbsc/tests/Makefile.am
@@ -4,6 +4,10 @@ if BUILD_NAT
 SUBDIRS += bsc-nat bsc-nat-trie
 endif
 
+if BUILD_BSC
+SUBDIRS += bsc
+endif
+
 if BUILD_SMPP
 SUBDIRS += smpp
 endif
diff --git a/openbsc/tests/atlocal.in b/openbsc/tests/atlocal.in
index bfbecd4..4635113 100644
--- a/openbsc/tests/atlocal.in
+++ b/openbsc/tests/atlocal.in
@@ -1,2 +1,3 @@
 enable_nat_test='@osmo_ac_build_nat@'
 enable_smpp_test='@osmo_ac_build_smpp@'
+enable_bsc_test='@osmo_ac_build_bsc@'
diff --git a/openbsc/tests/bsc/Makefile.am b/openbsc/tests/bsc/Makefile.am
new file mode 100644
index 0000000..202ba73
--- /dev/null
+++ b/openbsc/tests/bsc/Makefile.am
@@ -0,0 +1,19 @@
+AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include
+AM_CFLAGS=-Wall -ggdb3 $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOSCCP_CFLAGS) $(LIBOSMOABIS_CFLAGS) $(COVERAGE_CFLAGS)
+AM_LDFLAGS = $(COVERAGE_LDFLAGS)
+
+EXTRA_DIST = bsc_test.ok
+
+noinst_PROGRAMS = bsc_test
+
+bsc_test_SOURCES = bsc_test.c \
+			$(top_srcdir)/src/osmo-bsc/osmo_bsc_filter.c
+bsc_test_LDADD = $(top_builddir)/src/libbsc/libbsc.a \
+			$(top_srcdir)/src/libmsc/libmsc.a \
+			$(top_srcdir)/src/libctrl/libctrl.a \
+			$(top_srcdir)/src/libmgcp/libmgcp.a \
+			$(top_srcdir)/src/libtrau/libtrau.a \
+			$(top_srcdir)/src/libcommon/libcommon.a \
+			$(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) -lrt \
+			$(LIBOSMOSCCP_LIBS) $(LIBOSMOVTY_LIBS) \
+			$(LIBOSMOABIS_LIBS)
diff --git a/openbsc/tests/bsc/bsc_test.c b/openbsc/tests/bsc/bsc_test.c
new file mode 100644
index 0000000..1a089ae
--- /dev/null
+++ b/openbsc/tests/bsc/bsc_test.c
@@ -0,0 +1,193 @@
+/*
+ * BSC Message filtering
+ *
+ * (C) 2013 by Jacob Erlbeck <jerlbeck at sysmocom.de>
+ * (C) 2010-2013 by Holger Hans Peter Freyther <zecke at selfish.org>
+ * (C) 2010-2013 by On-Waves
+ *
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+
+#include <openbsc/debug.h>
+#include <openbsc/gsm_data.h>
+
+#include <openbsc/osmo_bsc.h>
+#include <openbsc/osmo_msc_data.h>
+#include <openbsc/gsm_04_80.h>
+#include <openbsc/gsm_subscriber.h>
+
+#include <osmocom/core/application.h>
+#include <osmocom/core/backtrace.h>
+#include <osmocom/core/talloc.h>
+
+#include <stdio.h>
+#include <search.h>
+
+enum test {
+	TEST_SCAN_TO_BTS,
+	TEST_SCAN_TO_MSC,
+};
+
+/* GSM 04.08 MM INFORMATION test message */
+static uint8_t gsm48_mm_info_nn_tzt[] = {
+	0x05, 0x32, 0x45, 0x08, 0x80, 0x4f, 0x77, 0xeb,
+       	0x1a, 0xb6, 0x97, 0xe7, 0x47, 0x31, 0x90, 0x61,
+       	0x11, 0x02, 0x73, 0x00,
+};
+
+static uint8_t gsm48_mm_info_nn_tzt_out[] = {
+	0x05, 0x32, 0x45, 0x08, 0x80, 0x4f, 0x77, 0xeb,
+	0x1a, 0xb6, 0x97, 0xe7, 0x47, 0x31, 0x90, 0x61,
+	0x11, 0x02, 0x73, 0x1a,
+};
+
+static uint8_t gsm48_mm_info_nn_tzt_dst[] = {
+	0x05, 0x32, 0x45, 0x08, 0x80, 0x4f, 0x77, 0xeb,
+       	0x1a, 0xb6, 0x97, 0xe7, 0x47, 0x31, 0x90, 0x61,
+       	0x11, 0x02, 0x73, 0x00, 0x49, 0x01, 0x00, 
+};
+
+static uint8_t gsm48_mm_info_nn_tzt_dst_out[] = {
+	0x05, 0x32, 0x45, 0x08, 0x80, 0x4f, 0x77, 0xeb,
+	0x1a, 0xb6, 0x97, 0xe7, 0x47, 0x31, 0x90, 0x61,
+	0x11, 0x02, 0x73, 0x1a, 0x49, 0x01, 0x02, 
+};
+
+struct test_definition {
+	const uint8_t *data;
+	const uint16_t length;
+	const int dir;
+	const int result;
+	const uint8_t *out_data;
+	const uint16_t out_length;
+	const char* params;
+	const int n_params;
+};
+
+static int get_int(const char *params, size_t nmemb, const char *key, int def, int *is_set)
+{
+	const char *kv = NULL;
+
+	kv = strstr(params, key);
+	if (kv) {
+		kv += strlen(key) + 1;
+		fprintf(stderr, "get_int(%s) -> %d\n", key, atoi(kv));
+		if (is_set)
+			*is_set = 1;
+	}
+
+	return kv ? atoi(kv) : def;
+}
+
+static const struct test_definition test_scan_defs[] = {
+	{
+		.data = gsm48_mm_info_nn_tzt_dst,
+		.length = ARRAY_SIZE(gsm48_mm_info_nn_tzt),
+		.dir = TEST_SCAN_TO_BTS,
+		.result = 0,
+		.out_data = gsm48_mm_info_nn_tzt_dst_out,
+		.out_length = ARRAY_SIZE(gsm48_mm_info_nn_tzt_out),
+		.params = "tz_hr=-5 tz_mn=15 tz_dst=2",
+		.n_params = 3,
+	},
+	{
+		.data = gsm48_mm_info_nn_tzt_dst,
+		.length = ARRAY_SIZE(gsm48_mm_info_nn_tzt_dst),
+		.dir = TEST_SCAN_TO_BTS,
+		.result = 0,
+		.out_data = gsm48_mm_info_nn_tzt_dst_out,
+		.out_length = ARRAY_SIZE(gsm48_mm_info_nn_tzt_dst_out),
+		.params = "tz_hr=-5 tz_mn=15 tz_dst=2",
+		.n_params = 3,
+	},
+};
+
+static void test_scan(void)
+{
+	void *text_ctx = talloc_named_const(NULL, 1, "testbsc");
+	int i;
+
+	struct gsm_network *net = talloc_zero(text_ctx, struct gsm_network);
+	struct gsm_bts *bts = talloc_zero(text_ctx, struct gsm_bts);
+	struct osmo_bsc_sccp_con *sccp_con = talloc_zero(text_ctx, struct osmo_bsc_sccp_con);
+	struct osmo_msc_data *msc = talloc_zero(text_ctx, struct osmo_msc_data);
+	struct gsm_subscriber_connection *conn = talloc_zero(text_ctx, struct gsm_subscriber_connection);
+
+	bts->network = net;
+	sccp_con->msc = msc;
+	conn->bts = bts;
+	conn->sccp_con = sccp_con;
+
+	/* start testinh with proper messages */
+	printf("Testing BTS<->MSC message scan.\n");
+	for (i = 0; i < ARRAY_SIZE(test_scan_defs); ++i) {
+		const struct test_definition *test_def = &test_scan_defs[i];
+		int result;
+		struct msgb *msg = msgb_alloc(4096, "test-message");
+		int is_set = 0;
+
+		bts->tz.hr = get_int(test_def->params, test_def->n_params, "tz_hr", 0, &is_set);
+		bts->tz.mn = get_int(test_def->params, test_def->n_params, "tz_mn", 0, &is_set);
+		bts->tz.dst = get_int(test_def->params, test_def->n_params, "tz_dst", 0, &is_set);
+		bts->tz.override = get_int(test_def->params, test_def->n_params, "tz_dst", is_set ? 1 : 0, NULL);
+
+		printf("Going to test item: %d\n", i);
+		msg->l3h = msgb_put(msg, test_def->length);
+		memcpy(msg->l3h, test_def->data, test_def->length);
+
+		switch (test_def->dir) {
+			case TEST_SCAN_TO_BTS:
+				result = bsc_scan_msc_msg(conn, msg);
+				break;
+			case TEST_SCAN_TO_MSC:
+				result = bsc_scan_msc_msg(conn, msg);
+				break;
+		}
+
+		if (result != test_def->result) {
+			printf("FAIL: Not the expected result, got: %d wanted: %d\n",
+				result, test_def->result);
+			goto out;
+		}
+
+		if (msgb_l3len(msg) != test_def->out_length) {
+			printf("FAIL: Not the expected message size, got: %d wanted: %d\n",
+				msgb_l3len(msg), test_def->out_length);
+			goto out;
+		}
+
+		if (memcmp(msgb_l3(msg), test_def->out_data, test_def->out_length) != 0) {
+			printf("FAIL: Not the expected message\n");
+			goto out;
+		}
+
+out:
+		msgb_free(msg);
+	}
+}
+
+
+int main(int argc, char **argv)
+{
+	osmo_init_logging(&log_info);
+
+	test_scan();
+
+	printf("Testing execution completed.\n");
+	return 0;
+}
diff --git a/openbsc/tests/bsc/bsc_test.ok b/openbsc/tests/bsc/bsc_test.ok
new file mode 100644
index 0000000..0564bf0
--- /dev/null
+++ b/openbsc/tests/bsc/bsc_test.ok
@@ -0,0 +1,4 @@
+Testing BTS<->MSC message scan.
+Going to test item: 0
+Going to test item: 1
+Testing execution completed.
diff --git a/openbsc/tests/testsuite.at b/openbsc/tests/testsuite.at
index e54d4b5..240f5e2 100644
--- a/openbsc/tests/testsuite.at
+++ b/openbsc/tests/testsuite.at
@@ -68,3 +68,11 @@ AT_KEYWORDS([abis])
 cat $abs_srcdir/abis/abis_test.ok > expout
 AT_CHECK([$abs_top_builddir/tests/abis/abis_test], [], [expout], [ignore])
 AT_CLEANUP
+
+AT_SETUP([bsc])
+AT_KEYWORDS([bsc])
+AT_CHECK([test "$enable_bsc_test" != no || exit 77])
+cat $abs_srcdir/bsc/bsc_test.ok > expout
+AT_CHECK([$abs_top_builddir/tests/bsc/bsc_test], [], [expout], [ignore])
+AT_CLEANUP
+
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