Hi Harald,

Thanks for the input.  Here's the updated patch.

Gus

On Wed, Nov 30, 2011 at 11:47 PM, Harald Welte <[email protected]> wrote:
> Hi Gus,
>
> On Wed, Nov 30, 2011 at 03:13:04PM -0800, Gus Bourg wrote:
>> Attached is a patch to support sending time to the device.
>
> thanks a lot for the patch.
>
> however, some remarks:
>
> 1) We actually do support ranges with negative numbers in the syntax,
>   after commit 33f0fc3c9565308044c934c9e0c1bb81c1a26311 in libosmocore
>   you can do something like "timezone <-19-19> (0|15|30|45)"
>   which I believe would be a more human-friendly way of entering it in
>   hours and minutes.
>
> 2) the internal storage could thus also be a simple "int timezone",
>   which gets filled from the hour and minute part of the abovementioned
>   command syntax.
>
> 3) please make sure to use a default of "cur_time->tm_gmtoff" in case
>   the config file doesn't use per-BTS timezones.  So another "int
>   timezone_bts_specific" member might be applicable.
>
> 4) please make sure to use tab instead of "        " (sequence of 8
>   whitespaces), or use a script that automatically takes care of that.
>
> 5) the "timezone" vty line should only be printed if the user actually
>   configured it (i.e. timezone_bts_specific == 1).
>
> 6) there needs to be a way to completely remove the timezone statement,
>   most likely a "no timezone" VTY command in the BTS node.
>
> Regards,
>        Harald
>
> --
> - Harald Welte <[email protected]>           http://laforge.gnumonks.org/
> ============================================================================
> "Privacy in residential applications is a desirable marketing option."
>                                                  (ETSI EN 300 175-7 Ch. A6)
diff --git a/openbsc/include/openbsc/gsm_data_shared.h b/openbsc/include/openbsc/gsm_data_shared.h
index f7a85a3..25e90ed 100644
--- a/openbsc/include/openbsc/gsm_data_shared.h
+++ b/openbsc/include/openbsc/gsm_data_shared.h
@@ -473,6 +473,11 @@ struct gsm_bts {
 	/* buffers where we put the pre-computed SI */
 	sysinfo_buf_t si_buf[_MAX_SYSINFO_TYPE];
 
+	/* TimeZone hours, mins, and bts specific */
+	int tzhr;
+	int tzmn;
+	int tz_bts_specific;
+
 	/* ip.accesss Unit ID's have Site/BTS/TRX layout */
 	union {
 		struct {
diff --git a/openbsc/src/libbsc/bsc_vty.c b/openbsc/src/libbsc/bsc_vty.c
index 724486f..ed74397 100644
--- a/openbsc/src/libbsc/bsc_vty.c
+++ b/openbsc/src/libbsc/bsc_vty.c
@@ -448,6 +448,8 @@ 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_bts_specific != 0)
+		vty_out(vty, "  timezone %d %d%s", bts->tzhr, bts->tzmn, 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);
@@ -1495,6 +1497,31 @@ DEFUN(cfg_bts_bsic,
 	return CMD_SUCCESS;
 }
 
+DEFUN(cfg_bts_timezone,
+      cfg_bts_timezone_cmd,
+      "timezone <-19-19> (0|15|30|45)",
+      "Set the Timezone Offset of this BTS\n")
+{
+	struct gsm_bts *bts = vty->index;
+	int tzhr = atoi(argv[0]);
+	int tzmn = atoi(argv[1]);
+
+	bts->tzhr = tzhr;
+	bts->tzmn = tzmn;
+	bts->tz_bts_specific=1;
+
+	return CMD_SUCCESS;
+}
+
+DEFUN(cfg_bts_no_timezone,
+      cfg_bts_no_timezone_cmd,
+      "no timezone",
+      "disable bts specific timezone\n")
+{
+	struct gsm_bts *bts = vty->index;
+	bts->tz_bts_specific=0;
+	return CMD_SUCCESS;
+}
 
 DEFUN(cfg_bts_unit_id,
       cfg_bts_unit_id_cmd,
@@ -2691,6 +2718,8 @@ int bsc_vty_init(const struct log_info *cat)
 	install_element(BTS_NODE, &cfg_bts_tsc_cmd);
 	install_element(BTS_NODE, &cfg_bts_bsic_cmd);
 	install_element(BTS_NODE, &cfg_bts_unit_id_cmd);
+	install_element(BTS_NODE, &cfg_bts_timezone_cmd);
+	install_element(BTS_NODE, &cfg_bts_no_timezone_cmd);
 	install_element(BTS_NODE, &cfg_bts_serno_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/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 7bf62b7..ec1afa7 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -610,12 +610,17 @@ static int mm_rx_loc_upd_req(struct gsm_subscriber_connection *conn, struct msgb
 	return gsm0408_authorize(conn, msg);
 }
 
-#if 0
-static uint8_t to_bcd8(uint8_t val)
+/* Turn int into semi-octet representation: 98 => 0x89 */
+static uint8_t bcdify(uint8_t value)
 {
-       return ((val / 10) << 4) | (val % 10);
+        uint8_t ret;
+
+        ret = value / 10;
+        ret |= (value % 10) << 4;
+
+        return ret;
 }
-#endif
+
 
 /* Section 9.2.15a */
 int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn)
@@ -623,13 +628,13 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn)
 	struct msgb *msg = gsm48_msgb_alloc();
 	struct gsm48_hdr *gh;
 	struct gsm_network *net = conn->bts->network;
+	struct gsm_bts *bts = conn->bts;
 	uint8_t *ptr8;
 	int name_len, name_pad;
-#if 0
+
 	time_t cur_t;
 	struct tm* cur_time;
-	int tz15min;
-#endif
+	int tzunits;
 
 	msg->lchan = conn->lchan;
 
@@ -696,24 +701,41 @@ int gsm48_tx_mm_info(struct gsm_subscriber_connection *conn)
 
 	}
 
-#if 0
 	/* Section 10.5.3.9 */
 	cur_t = time(NULL);
 	cur_time = gmtime(&cur_t);
+
 	ptr8 = msgb_put(msg, 8);
 	ptr8[0] = GSM48_IE_NET_TIME_TZ;
-	ptr8[1] = to_bcd8(cur_time->tm_year % 100);
-	ptr8[2] = to_bcd8(cur_time->tm_mon);
-	ptr8[3] = to_bcd8(cur_time->tm_mday);
-	ptr8[4] = to_bcd8(cur_time->tm_hour);
-	ptr8[5] = to_bcd8(cur_time->tm_min);
-	ptr8[6] = to_bcd8(cur_time->tm_sec);
-	/* 02.42: coded as BCD encoded signed value in units of 15 minutes */
-	tz15min = (cur_time->tm_gmtoff)/(60*15);
-	ptr8[7] = to_bcd8(tz15min);
-	if (tz15min < 0)
-		ptr8[7] |= 0x80;
-#endif
+	ptr8[1] = bcdify(cur_time->tm_year % 100);
+	ptr8[2] = bcdify(cur_time->tm_mon + 1);
+	ptr8[3] = bcdify(cur_time->tm_mday);
+	ptr8[4] = bcdify(cur_time->tm_hour);
+	ptr8[5] = bcdify(cur_time->tm_min);
+	ptr8[6] = bcdify(cur_time->tm_sec);
+
+	if (bts->tz_bts_specific) {
+		/* Convert tzhr and tzmn to units */
+		if (bts->tzhr < 0) {
+			tzunits = ((bts->tzhr/-1)*4);
+			tzunits = tzunits + (bts->tzmn%15);
+			ptr8[7] = bcdify(tzunits);
+			/* Set negative time */
+			ptr8[7] |= 0x08;
+		}
+		else {
+			tzunits = bts->tzhr*4;
+			tzunits = tzunits + (bts->tzmn%15);
+			ptr8[7] = bcdify(tzunits);
+		}
+	}
+	else {
+		/* Need to get GSM offset and convert into 15 min units */
+		tzunits = (cur_time->tm_gmtoff)/(60*15);
+		ptr8[7] = bcdify(tzunits);
+		if (tzunits < 0)
+			ptr8[7] |= 0x08;
+	}
 
 	DEBUGP(DMM, "-> MM INFO\n");
 

Reply via email to