Skip to content

Commit 9e6fb03

Browse files
authored
Merge pull request #420 from theori-io/here-images-tm
Use struct tm to represent HERE Images time
2 parents 1730abd + a7f7b97 commit 9e6fb03

File tree

5 files changed

+45
-32
lines changed

5 files changed

+45
-32
lines changed

include/nrsc5.h

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -515,18 +515,18 @@ struct nrsc5_event_t
515515
const int *locations;
516516
} emergency_alert;
517517
struct {
518-
int image_type; /**< NRSC5_HERE_IMAGE_TRAFFIC or NRSC5_HERE_IMAGE_WEATHER */
519-
int seq; /**< sequence number (1-15); increments when traffic/weather image changes */
520-
int n1; /**< part number (1-9) for traffic, or incrementing sequence number for weather */
521-
int n2; /**< number of parts (9) for traffic, or incrementing sequence number for weather */
522-
unsigned int timestamp; /**< unix timestamp of traffic or weather image */
523-
float latitude1; /**< latitude of north map edge */
524-
float longitude1; /**< longitude of west map edge */
525-
float latitude2; /**< latitude of south map edge */
526-
float longitude2; /**< longitude of east map edge */
527-
const char *name; /**< filename, e.g. "trafficMap_1_2_rdhs.png" or "WeatherImage_0_0_rdhs.png" */
528-
unsigned int size; /**< size of image file, in bytes */
529-
const uint8_t *data; /**< contents of image file */
518+
int image_type; /**< NRSC5_HERE_IMAGE_TRAFFIC or NRSC5_HERE_IMAGE_WEATHER */
519+
int seq; /**< sequence number (1-15); increments when traffic/weather image changes */
520+
int n1; /**< part number (1-9) for traffic, or incrementing sequence number for weather */
521+
int n2; /**< number of parts (9) for traffic, or incrementing sequence number for weather */
522+
struct tm *time_utc; /**< UTC time of traffic or weather image */
523+
float latitude1; /**< latitude of north map edge */
524+
float longitude1; /**< longitude of west map edge */
525+
float latitude2; /**< latitude of south map edge */
526+
float longitude2; /**< longitude of east map edge */
527+
const char *name; /**< filename, e.g. "trafficMap_1_2_rdhs.png" or "WeatherImage_0_0_rdhs.png" */
528+
unsigned int size; /**< size of image file, in bytes */
529+
const uint8_t *data; /**< contents of image file */
530530
} here_image;
531531
};
532532
};

src/main.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,11 @@ static void dump_aas_file(state_t *st, const nrsc5_event_t *evt)
245245
name = evt->here_image.name;
246246
data = evt->here_image.data;
247247
size = evt->here_image.size;
248-
number = evt->here_image.timestamp;
248+
#if defined(WIN32) || defined(_WIN32)
249+
number = _mkgmtime64(evt->here_image.time_utc);
250+
#else
251+
number = timegm(evt->here_image.time_utc);
252+
#endif
249253
break;
250254
default:
251255
log_error("invalid event type");
@@ -255,7 +259,7 @@ static void dump_aas_file(state_t *st, const nrsc5_event_t *evt)
255259
char fullpath[strlen(st->aas_files_path) + strlen(name) + 16];
256260
FILE *fp;
257261

258-
sprintf(fullpath, "%s" PATH_SEPARATOR "%d_%s", st->aas_files_path, number, name);
262+
sprintf(fullpath, "%s" PATH_SEPARATOR "%u_%s", st->aas_files_path, number, name);
259263
fp = fopen(fullpath, "wb");
260264
if (fp == NULL)
261265
{
@@ -495,8 +499,7 @@ static void callback(const nrsc5_event_t *evt, void *opaque)
495499
case NRSC5_EVENT_HERE_IMAGE:
496500
if (st->aas_files_path)
497501
dump_aas_file(st, evt);
498-
time_t ts = (time_t) evt->here_image.timestamp;
499-
strftime(time_str, sizeof(time_str), "%Y-%m-%dT%H:%M:%SZ", gmtime(&ts));
502+
strftime(time_str, sizeof(time_str), "%Y-%m-%dT%H:%M:%SZ", evt->here_image.time_utc);
500503
log_info("HERE Image: type=%s, seq=%d, n1=%d, n2=%d, time=%s, lat1=%.5f, lon1=%.5f, lat2=%.5f, lon2=%.5f, name=%s, size=%d",
501504
evt->here_image.image_type == NRSC5_HERE_IMAGE_TRAFFIC ? "TRAFFIC" : "WEATHER",
502505
evt->here_image.seq,

src/nrsc5.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,13 @@ void nrsc5_report_here_image(nrsc5_t *st, int image_type, int seq, int n1, int n
10531053
evt.here_image.seq = seq;
10541054
evt.here_image.n1 = n1;
10551055
evt.here_image.n2 = n2;
1056-
evt.here_image.timestamp = timestamp;
1056+
#if defined(WIN32) || defined(_WIN32)
1057+
__time64_t ts = (__time64_t) timestamp;
1058+
evt.here_image.time_utc = _gmtime64(&ts);
1059+
#else
1060+
time_t ts = (time_t) timestamp;
1061+
evt.here_image.time_utc = gmtime(&ts);
1062+
#endif
10571063
evt.here_image.latitude1 = latitude1;
10581064
evt.here_image.longitude1 = longitude1;
10591065
evt.here_image.latitude2 = latitude2;

support/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -319,12 +319,12 @@ def callback(self, evt_type, evt):
319319
evt.common_delay,
320320
evt.latency)
321321
elif evt_type == nrsc5.EventType.HERE_IMAGE:
322-
time_str = evt.timestamp.strftime("%Y-%m-%dT%H:%M:%SZ")
322+
time_str = evt.time_utc.strftime("%Y-%m-%dT%H:%M:%SZ")
323323
logging.info("HERE Image: type=%s, seq=%d, n1=%d, n2=%d, time=%s, lat1=%.5f, lon1=%.5f, lat2=%.5f, lon2=%.5f, name=%s, size=%d",
324324
evt.image_type.name, evt.seq, evt.n1, evt.n2, time_str, evt.latitude1, evt.longitude1,
325325
evt.latitude2, evt.longitude2, evt.name, len(evt.data))
326326
if self.args.dump_aas_files:
327-
time_int = int(evt.timestamp.timestamp())
327+
time_int = int(evt.time_utc.timestamp())
328328
path = os.path.join(self.args.dump_aas_files, f"{time_int}_{evt.name}")
329329
with open(path, "wb") as file:
330330
file.write(evt.data)

support/nrsc5.py

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ class HEREImageType(enum.Enum):
203203
EmergencyAlert = collections.namedtuple("EmergencyAlert", ["message", "control_data", "categories", "location_format", "locations"])
204204
AudioService = collections.namedtuple("AudioService", ["program", "access", "type", "codec_mode", "blend_control",
205205
"digital_audio_gain", "common_delay", "latency"])
206-
HEREImage = collections.namedtuple("HEREImage", ["image_type", "seq", "n1", "n2", "timestamp", "latitude1", "longitude1",
206+
HEREImage = collections.namedtuple("HEREImage", ["image_type", "seq", "n1", "n2", "time_utc", "latitude1", "longitude1",
207207
"latitude2", "longitude2", "name", "data"])
208208

209209

@@ -521,7 +521,7 @@ class _HEREImage(ctypes.Structure):
521521
("seq", ctypes.c_int),
522522
("n1", ctypes.c_int),
523523
("n2", ctypes.c_int),
524-
("timestamp", ctypes.c_uint),
524+
("time_utc", ctypes.POINTER(_TimeStruct)),
525525
("latitude1", ctypes.c_float),
526526
("longitude1", ctypes.c_float),
527527
("latitude2", ctypes.c_float),
@@ -591,6 +591,18 @@ def _decode(string):
591591
return string
592592
return string.decode()
593593

594+
@staticmethod
595+
def _timestruct_to_datetime(ts):
596+
return datetime.datetime(
597+
ts.contents.tm_year + 1900,
598+
ts.contents.tm_mon + 1,
599+
ts.contents.tm_mday,
600+
ts.contents.tm_hour,
601+
ts.contents.tm_min,
602+
ts.contents.tm_sec,
603+
tzinfo=datetime.timezone.utc
604+
)
605+
594606
def _callback_wrapper(self, c_evt):
595607
c_evt = c_evt.contents
596608
evt = None
@@ -683,16 +695,7 @@ def _callback_wrapper(self, c_evt):
683695
lot = c_evt.u.lot
684696
service = self.services[lot.service.contents.number]
685697
component = self.components[(lot.service.contents.number, lot.component.contents.id)]
686-
expiry_struct = lot.expiry_utc.contents
687-
expiry_time = datetime.datetime(
688-
expiry_struct.tm_year + 1900,
689-
expiry_struct.tm_mon + 1,
690-
expiry_struct.tm_mday,
691-
expiry_struct.tm_hour,
692-
expiry_struct.tm_min,
693-
expiry_struct.tm_sec,
694-
tzinfo=datetime.timezone.utc
695-
)
698+
expiry_time = self._timestruct_to_datetime(lot.expiry_utc)
696699
evt = LOT(lot.port, lot.lot, MIMEType(lot.mime), self._decode(lot.name), lot.data[:lot.size], expiry_time, service, component)
697700
elif evt_type == EventType.SIS:
698701
sis = c_evt.u.sis
@@ -774,12 +777,13 @@ def _callback_wrapper(self, c_evt):
774777
)
775778
elif evt_type == EventType.HERE_IMAGE:
776779
here_image = c_evt.u.here_image
780+
time_utc = self._timestruct_to_datetime(here_image.time_utc)
777781
evt = HEREImage(
778782
HEREImageType(here_image.image_type),
779783
here_image.seq,
780784
here_image.n1,
781785
here_image.n2,
782-
datetime.datetime.fromtimestamp(here_image.timestamp, tz=datetime.timezone.utc),
786+
time_utc,
783787
here_image.latitude1,
784788
here_image.longitude1,
785789
here_image.latitude2,

0 commit comments

Comments
 (0)