1 /*
2  * DVB time functions
3  * Copyright (C) 2010-2011 Unix Solutions Ltd.
4  *
5  * Released under MIT license.
6  * See LICENSE-MIT.txt for license terms.
7  */
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <netdb.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <time.h>
14 
15 #include "tsfuncs.h"
16 
ts_time_encode_bcd(int duration_sec)17 uint32_t ts_time_encode_bcd(int duration_sec) {
18 	int t_sec, t_min, t_hour, ret;
19 	t_sec  = duration_sec % 60;
20 	t_min  = (duration_sec - t_sec) / 60;
21 	t_hour = (t_min - t_min % 60) / 60;
22 	t_min  = t_min - t_hour * 60;
23 
24 	ret  = dec2bcd(t_hour) << 16;
25 	ret |= dec2bcd(t_min ) << 8;
26 	ret |= dec2bcd(t_sec );
27 
28 	return ret;
29 }
30 
ts_time_decode_bcd(int duration_bcd,int * duration_sec,int * hour,int * min,int * sec)31 void ts_time_decode_bcd(int duration_bcd, int *duration_sec, int *hour, int *min, int *sec) {
32 	*hour = bcd2dec( (duration_bcd &~ 0xff00ffff) >> 16 );	// 11111111 xxxxxxxx xxxxxxxx
33 	*min  = bcd2dec( (duration_bcd &~ 0xffff00ff) >> 8 );	// xxxxxxxx 11111111 xxxxxxxx
34 	*sec  = bcd2dec( (duration_bcd &~ 0xffffff00) );		// xxxxxxxx xxxxxxxx 11111111
35 	if (duration_sec)
36 		*duration_sec = *hour * 3600 + *min * 60 + *sec;
37 }
38 
ts_time_encode_mjd(uint16_t * mjd,uint32_t * bcd,time_t * ts,struct tm * tm)39 void ts_time_encode_mjd(uint16_t *mjd, uint32_t *bcd, time_t *ts, struct tm *tm) {
40 	struct tm *ltm = tm;
41 	if (!ts && !tm)
42 		return;
43 	if (ts) { // Decompose ts into struct tm
44 		struct tm dectm;
45 		gmtime_r(ts, &dectm);
46 		ltm = &dectm;
47 	}
48 	if (!ltm) // Paranoia
49 		return;
50 	if (mjd) { // Encode ymd into mjd
51 		int Y = ltm->tm_year; // 1900 + Y gives the real year
52 		int M = ltm->tm_mon + 1;
53 		int D = ltm->tm_mday;
54 		int L = (M == 1 || M == 2) ? 1 : 0;
55 		*mjd = 14956 + D + (int)((Y - L) * 365.25) + (int)((M + 1 + L * 12) * 30.6001);
56 	}
57 	if (bcd) { // Encode hms into bcd
58 		*bcd  = 0;
59 		*bcd  = dec2bcd(ltm->tm_hour) << 16;
60 		*bcd |= dec2bcd(ltm->tm_min ) << 8;
61 		*bcd |= dec2bcd(ltm->tm_sec );
62 	}
63 }
64 
ts_time_decode_mjd(uint16_t mjd,uint32_t bcd,struct tm * tm)65 time_t ts_time_decode_mjd(uint16_t mjd, uint32_t bcd, struct tm *tm) {
66 	int year = 0, month = 0, day = 0;
67 	int hour = 0, min = 0, sec = 0;
68 	time_t ret = 0;
69 	if (mjd > 0) {
70 		long tmp;
71 		// Copied from ETSI EN 300 468 (ANNEX C)
72 		year  = (int)((mjd - 15078.2) / 365.25);
73 		month = (int)((mjd - 14956.1 - (int)(year * 365.25)) / 30.6001);
74 		day   = mjd - 14956 - (int)(year * 365.25) - (int)(month * 30.6001);
75 		tmp   = (month == 14 || month == 15) ? 1 : 0;
76 		year  = year + tmp;
77 		month = month - 1 - tmp * 12;
78 		year  += 1900;
79 	}
80 	if (bcd > 0) {
81 		ts_time_decode_bcd(bcd, NULL, &hour, &min, &sec);
82 	}
83 	if (tm) {
84 		memset(tm, 0, sizeof(struct tm));
85 		tm->tm_year = year - 1900;
86 		tm->tm_mon  = month - 1;
87 		tm->tm_mday = day;
88 		tm->tm_hour = hour;
89 		tm->tm_min  = min;
90 		tm->tm_sec  = sec;
91 		ret = timegm(tm);
92 	}
93 	return ret;
94 }
95