@@ -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) */