[RFC 1/1] gsm0411_utils: Fix timezone offs calculation in gsm340_gen_scts()

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

Daniel Willmann dwillmann at sysmocom.de
Wed Mar 26 17:36:54 UTC 2014


The current code uses gmtime which returns the time in UTC. This is not
the intended behaviour (otherwise the offset could always be set to
zero).

This uses localtime as well as gmtime to calculate the timezone offset
instead of relying on tm_gmtoff.
This means three extra function calls (mktime * 2, gmtime_r), but this
is completely independent of non-standard features.
---
 src/gsm/gsm0411_utils.c | 41 +++++++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 16 deletions(-)

diff --git a/src/gsm/gsm0411_utils.c b/src/gsm/gsm0411_utils.c
index bb59a10..18664dc 100644
--- a/src/gsm/gsm0411_utils.c
+++ b/src/gsm/gsm0411_utils.c
@@ -77,23 +77,32 @@ uint8_t gsm411_unbcdify(uint8_t value)
 /* Generate 03.40 TP-SCTS */
 void gsm340_gen_scts(uint8_t *scts, time_t time)
 {
-	struct tm *tm = gmtime(&time);
-
-	*scts++ = gsm411_bcdify(tm->tm_year % 100);
-	*scts++ = gsm411_bcdify(tm->tm_mon + 1);
-	*scts++ = gsm411_bcdify(tm->tm_mday);
-	*scts++ = gsm411_bcdify(tm->tm_hour);
-	*scts++ = gsm411_bcdify(tm->tm_min);
-	*scts++ = gsm411_bcdify(tm->tm_sec);
-#ifdef HAVE_TM_GMTOFF_IN_TM
-	if (tm->tm_gmtoff >= 0)
-		*scts++ = gsm411_bcdify(tm->tm_gmtoff/(60*15));
+	struct tm tm_local, tm_utc;
+	time_t ts_local, ts_utc, gmtoffset;
+
+	localtime_r(&time, &tm_local);
+
+	*scts++ = gsm411_bcdify(tm_local.tm_year % 100);
+	*scts++ = gsm411_bcdify(tm_local.tm_mon + 1);
+	*scts++ = gsm411_bcdify(tm_local.tm_mday);
+	*scts++ = gsm411_bcdify(tm_local.tm_hour);
+	*scts++ = gsm411_bcdify(tm_local.tm_min);
+	*scts++ = gsm411_bcdify(tm_local.tm_sec);
+
+	/* Figure out the timezone offset in a portable way.
+	 * The idea is to convert the time_t into local and UTC struct tm
+	 * representations and then calculate the difference of both. */
+	gmtime_r(&time, &tm_utc);
+	tm_utc.is_dst = 0;
+	tm_local.is_dst = 0;
+	ts_utc = mktime(&tm_utc);
+	ts_local = mktime(&tm_local);
+	gmtoffset = ts_local - ts_utc;
+
+	if (gmtoffset >= 0)
+		*scts++ = gsm411_bcdify(gmtoffset/(60*15));
 	else
-		*scts++ = gsm411_bcdify(-tm->tm_gmtoff/(60*15)) | 0x80;
-#else
-#warning find a portable way to obtain timezone offset
-	*scts++ = 0;
-#endif
+		*scts++ = gsm411_bcdify(-gmtoffset/(60*15)) | 0x80;
 }
 
 /* Decode 03.40 TP-SCTS (into utc/gmt timestamp) */
-- 
1.8.4.2





More information about the OpenBSC mailing list