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

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.

Sponsored-by: On-Waves ehf
Ticket: OW#978
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index d156716..5d03b2a 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -489,8 +489,14 @@
 		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);
@@ -1621,6 +1627,32 @@
 
 	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;
@@ -3117,6 +3149,7 @@
 	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);