Browse Source

Use standart section parsers and generators for TDT/TOT

Georgi Chorbadzhiyski 9 years ago
parent
commit
c76b1c8b21
5 changed files with 304 additions and 277 deletions
  1. 1
    1
      Makefile
  2. 1
    11
      tsdata.h
  3. 5
    3
      tsfuncs.h
  4. 137
    262
      tsfuncs_tdt.c
  5. 160
    0
      tsfuncs_tdt_desc.c

+ 1
- 1
Makefile View File

@@ -14,7 +14,7 @@ OBJS = log.o tsfuncs.o tsfuncs_crc.o tsfuncs_misc.o tsfuncs_time.o \
14 14
 	tsfuncs_nit.o tsfuncs_nit_desc.o \
15 15
 	tsfuncs_sdt.o tsfuncs_sdt_desc.o \
16 16
 	tsfuncs_eit.o tsfuncs_eit_desc.o \
17
-	tsfuncs_tdt.o \
17
+	tsfuncs_tdt.o tsfuncs_tdt_desc.o \
18 18
 	tsfuncs_pes.o tsfuncs_pes_data.o \
19 19
 	tsfuncs_pes_es.o
20 20
 PROG = libts.a

+ 1
- 11
tsdata.h View File

@@ -228,15 +228,7 @@ struct ts_eit {
228 228
 
229 229
 struct ts_tdt {
230 230
 	struct ts_header			ts_header;
231
-
232
-	uint8_t		pointer_field;
233
-
234
-	uint8_t		table_id;
235
-
236
-	uint16_t	section_syntax_indicator: 1,	// Section Syntax Indicator
237
-				reserved_1              : 1,	// 1 reserved bit
238
-				reserved_2              : 2,	// 2 reserved bits
239
-				section_length          : 12;	// Section lenth
231
+	struct ts_section_header	*section_header;
240 232
 
241 233
 	uint16_t	mjd;							// This both are part of one 40 bit field (UTC_time)
242 234
 	uint32_t	bcd;							// Only 24 bits are used
@@ -245,10 +237,8 @@ struct ts_tdt {
245 237
 	uint16_t	reserved_3				: 4,
246 238
 				descriptors_size        : 12;
247 239
 	uint8_t		*descriptors;
248
-	uint32_t	CRC;
249 240
 
250 241
 	// The variables bellow are nor part of the physical packet
251
-	uint8_t		*packet_data;
252 242
 	time_t		utc;	// decoded UTC_time
253 243
 	struct tm	tm;		// decoded UTC_time
254 244
 

+ 5
- 3
tsfuncs.h View File

@@ -182,18 +182,20 @@ int				ts_eit_add_short_event_descriptor	(struct ts_eit *eit, uint16_t event_id,
182 182
 int				ts_eit_add_extended_event_descriptor(struct ts_eit *eit, uint16_t event_id, uint8_t running, time_t start_time, int duration_sec, char *text);
183 183
 
184 184
 // TDT
185
+struct ts_tdt *	ts_tdt_alloc();
185 186
 struct ts_tdt *	ts_tdt_alloc_init	(time_t ts);
186 187
 struct ts_tdt *	ts_tot_alloc_init	(time_t ts);
187 188
 void			ts_tdt_free			(struct ts_tdt **tdt);
188 189
 
189
-int				ts_tdt_parse		(struct ts_tdt *tdt, uint8_t *ts_packet);
190
-void			ts_tdt_generate		(struct ts_tdt *tdt, uint8_t *ts_packet);
190
+int				ts_tdt_parse		(struct ts_tdt *tdt);
191
+struct ts_tdt *	ts_tdt_push_packet	(struct ts_tdt *tdt, uint8_t *ts_packet);
192
+void			ts_tdt_generate		(struct ts_tdt *tdt, uint8_t **ts_packets, int *num_packets);
191 193
 void			ts_tdt_dump			(struct ts_tdt *tdt);
192 194
 
193 195
 void			ts_tdt_set_time		(struct ts_tdt *tdt, time_t ts);
194 196
 
195 197
 void			ts_tot_set_localtime_offset			(struct ts_tdt *tdt, time_t now, time_t change_time, uint8_t polarity, uint16_t ofs, uint16_t ofs_next);
196
-void			ts_tot_set_localtime_offset_sofia	(struct ts_tdt *tdt);
198
+void			ts_tot_set_localtime_offset_sofia	(struct ts_tdt *tdt, time_t now);
197 199
 
198 200
 // Time
199 201
 uint32_t		ts_time_encode_bcd	(int duration_sec);

+ 137
- 262
tsfuncs_tdt.c View File

@@ -9,182 +9,177 @@
9 9
 
10 10
 struct ts_tdt *ts_tdt_alloc() {
11 11
 	struct ts_tdt *tdt = calloc(1, sizeof(struct ts_tdt));
12
-	tdt->packet_data = malloc(TS_PACKET_SIZE);
13
-	memset(tdt->packet_data, 0x32, TS_PACKET_SIZE);
12
+	tdt->section_header	= ts_section_data_alloc();
14 13
 	return tdt;
15 14
 }
16 15
 
17 16
 void ts_tdt_free(struct ts_tdt **ptdt) {
18 17
 	struct ts_tdt *tdt = *ptdt;
19 18
 	if (tdt) {
20
-		FREE(tdt->packet_data);
19
+		ts_section_data_free(&tdt->section_header);
21 20
 		FREE(tdt->descriptors);
22 21
 		FREE(*ptdt);
23 22
 	}
24 23
 }
25 24
 
26
-static void ts_tdt_init_empty(struct ts_tdt *tdt, time_t ts, int tot) {
27
-	tdt->ts_header.pid            = 0x14;
28
-	tdt->ts_header.pusi           = 1;
29
-	tdt->ts_header.payload_field  = 1;
30
-	tdt->ts_header.payload_offset = 4;
31
-	tdt->ts_header.continuity     = 7;
32
-
33
-	tdt->table_id                 = 0x70;
34
-	tdt->section_syntax_indicator = 0;
35
-	tdt->reserved_1               = 1;
36
-	tdt->reserved_2               = 3;
37
-	tdt->section_length           = 5;
38
-
39
-	ts_time_encode_mjd(&tdt->mjd, &tdt->bcd, &ts, NULL);
25
+static struct ts_tdt *ts_tdt_reset(struct ts_tdt *tdt) {
26
+	struct ts_tdt *newtdt = ts_tdt_alloc();
27
+	ts_tdt_free(&tdt);
28
+	return newtdt;
29
+}
30
+
31
+struct ts_tdt *ts_tdt_push_packet(struct ts_tdt *tdt, uint8_t *ts_packet) {
32
+	struct ts_header ts_header;
33
+	memset(&ts_header, 0, sizeof(struct ts_header));
34
+
35
+	if (ts_packet_header_parse(ts_packet, &ts_header)) {
36
+		// TDT/TOT should be with PID 0x11
37
+		if (ts_header.pid != 0x14)
38
+			goto OUT;
39
+		if (!tdt->ts_header.pusi)
40
+			tdt->ts_header = ts_header;
41
+	}
42
+
43
+	if (ts_header.pusi) {
44
+		struct ts_section_header section_header;
45
+		memset(&section_header, 0, sizeof(struct ts_section_header));
46
+
47
+		uint8_t *section_data = ts_section_header_parse(ts_packet, &tdt->ts_header, &section_header);
48
+		if (!section_data) {
49
+			memset(&tdt->ts_header, 0, sizeof(struct ts_header));
50
+			goto OUT;
51
+		}
52
+		//    table_id should be 0x70 (time_date_section)
53
+		// or table_id should be 0x73 (time_offset_section)
54
+		if (section_header.table_id != 0x70 && section_header.table_id != 0x73) {
55
+			memset(&tdt->ts_header, 0, sizeof(struct ts_header));
56
+			goto OUT;
57
+		}
58
+
59
+		// Set correct section_header
60
+		ts_section_header_parse(ts_packet, &tdt->ts_header, tdt->section_header);
61
+	}
62
+
63
+	if (!tdt->initialized) {
64
+		ts_section_add_packet(tdt->section_header, &ts_header, ts_packet);
65
+		if (tdt->section_header->initialized) {
66
+			if (!ts_tdt_parse(tdt))
67
+				goto ERROR;
68
+		}
69
+	}
70
+
71
+OUT:
72
+	return tdt;
73
+
74
+ERROR:
75
+	return ts_tdt_reset(tdt);
76
+}
77
+
78
+int ts_tdt_parse(struct ts_tdt *tdt) {
79
+	struct ts_section_header *sec = tdt->section_header;
80
+	uint8_t *data = sec->data;
81
+
82
+	tdt->mjd = (data[0] << 8) | data[1];
83
+	tdt->bcd = ((data[2] << 16) | (data[3] << 8)) | data[4];
84
+	data += 5;
85
+
40 86
 	tdt->utc = ts_time_decode_mjd(tdt->mjd, tdt->bcd, &tdt->tm);
41 87
 
42
-	if (tot) {
43
-		tdt->table_id            = 0x73;
44
-		tdt->reserved_3          = 0xf;
45
-		tdt->descriptors_size    = 0;
46
-		tdt->CRC                 = 0;
47
-		tdt->section_length     += 2 + 4;	// 2 bytes reserved+descripts_size
48
-	}
49
-
50
-	ts_tdt_generate(tdt, tdt->packet_data);
51
-
52
-	tdt->initialized = 1;
53
-}
54
-
55
-struct ts_tdt *ts_tdt_alloc_init(time_t ts) {
56
-	struct ts_tdt *tdt = ts_tdt_alloc();
57
-	ts_tdt_init_empty(tdt, ts, 0);
58
-	return tdt;
59
-}
60
-
61
-struct ts_tdt *ts_tot_alloc_init(time_t ts) {
62
-	struct ts_tdt *tdt = ts_tdt_alloc();
63
-	ts_tdt_init_empty(tdt, ts, 1);
64
-	return tdt;
65
-}
66
-
67
-static void ts_tdt_check_generator(struct ts_tdt *tdt) {
68
-	struct ts_tdt *tdt1 = ts_tdt_alloc();
69
-	ts_tdt_parse(tdt1, tdt->packet_data);
70
-	ts_compare_data("TDT/TOT (packet->data)", tdt1->packet_data, tdt->packet_data, TS_PACKET_SIZE);
71
-	ts_tdt_free(&tdt1);
72
-
73
-	uint8_t *tmp = malloc(TS_PACKET_SIZE);
74
-	ts_tdt_generate(tdt, tmp);
75
-	ts_compare_data("TDT/TOT (data->packet)", tdt->packet_data, tmp, TS_PACKET_SIZE);
76
-	free(tmp);
77
-}
78
-
79
-int ts_tdt_parse(struct ts_tdt *tdt, uint8_t *ts_packet) {
80
-	uint8_t *data = ts_packet_header_parse(ts_packet, &tdt->ts_header);
81
-
82
-	if (!data)
83
-		return 0;
84
-
85
-	if (tdt->ts_header.pid != 0x14) // TOT/TDT
86
-		return 0;
87
-
88
-	tdt->pointer_field = data[0];
89
-	data += tdt->pointer_field + 1;
90
-
91
-	if ((data + 8) - ts_packet > TS_PACKET_SIZE) {
92
-		ts_LOGf("!!! Section start outside of TS packet!\n");
93
-		return 0;
94
-	}
95
-
96
-	if (data[0] != 0x70 && data[0] != 0x73) { // TDT or TOT
97
-		ts_LOGf("Invalid TDT/TOT Table_ID 0x%02x\n", data[0]);
98
-		return 0;
99
-	}
100
-
101
-	tdt->table_id                 = data[0];
102
-	tdt->section_syntax_indicator = data[1] >> 7;			// x1111111
103
-	tdt->reserved_1               = (data[1] &~ 0xBF) >> 6;	// 1x111111
104
-	tdt->reserved_2               = (data[1] &~ 0xCF) >> 4;	// 11xx1111
105
-	tdt->section_length           = ((data[1] &~ 0xF0) << 8) | data[2]; // 1111xxxx xxxxxxxx
106
-	if (tdt->section_length > TS_MAX_PAYLOAD_SIZE - 8) {
107
-		ts_LOGf("TDT/TOT section length is too big: %d (max: %d)\n", tdt->section_length, TS_MAX_PAYLOAD_SIZE - 8);
108
-		return 0;
109
-	}
110
-
111
-	tdt->mjd       = (data[3] << 8) | data[4];
112
-	tdt->bcd       = ((data[5] << 16) | (data[6] << 8)) | data[7];
113
-
114
-	if (tdt->table_id == 0x73) { // TOT
115
-		tdt->reserved_3        = data[8] >> 4;		// xxxx1111
116
-		tdt->descriptors_size  = data[8] &~ 0xf0;	// 1111xxxx
117
-		tdt->descriptors_size |= data[9];			// xxxxxxxx
118
-		if (tdt->descriptors_size > TS_MAX_PAYLOAD_SIZE - 10) {
119
-			ts_LOGf("TDT/TOT descriptors_size is too big: %d (max: %d)\n", tdt->descriptors_size, TS_MAX_PAYLOAD_SIZE - 10);
120
-			return 0;
121
-		}
88
+	if (sec->table_id == 0x73) { // TOT
89
+		tdt->reserved_3        = data[0] >> 4;		// xxxx1111
90
+		tdt->descriptors_size  = data[0] &~ 0xf0;	// 1111xxxx
91
+		tdt->descriptors_size |= data[1];			// xxxxxxxx
92
+		data += 2;
122 93
 		if (tdt->descriptors_size) {
123 94
 			tdt->descriptors = malloc(tdt->descriptors_size);
124
-			memcpy(tdt->descriptors, &data[10], tdt->descriptors_size);
95
+			memcpy(tdt->descriptors, data, tdt->descriptors_size);
125 96
 		}
126
-		tdt->CRC = (tdt->CRC << 8) | data[10 + tdt->descriptors_size + 3];
127
-		tdt->CRC = (tdt->CRC << 8) | data[10 + tdt->descriptors_size + 2];
128
-		tdt->CRC = (tdt->CRC << 8) | data[10 + tdt->descriptors_size + 1];
129
-		tdt->CRC = (tdt->CRC << 8) | data[10 + tdt->descriptors_size + 0];
97
+		if (!ts_crc32_section_check(tdt->section_header, "TOT"))
98
+			return 0;
130 99
 	}
131 100
 
132
-	tdt->utc = ts_time_decode_mjd(tdt->mjd, tdt->bcd, &tdt->tm);
133
-
134
-	memcpy(tdt->packet_data, ts_packet, TS_PACKET_SIZE);
135
-
136 101
 	tdt->initialized = 1;
137
-
138 102
 	return 1;
139 103
 }
140 104
 
141
-void ts_tdt_generate(struct ts_tdt *tdt, uint8_t *ts_packet) {
142
-	ts_packet_header_generate(ts_packet, &tdt->ts_header);
105
+void ts_tdt_generate(struct ts_tdt *tdt, uint8_t **ts_packets, int *num_packets) {
106
+	uint8_t *secdata = ts_section_data_alloc_section();
107
+	ts_section_header_generate(secdata, tdt->section_header, 0);
108
+	int curpos = 3; // Compensate for the section header, first data byte is at offset 3
143 109
 
144
-	uint8_t start = 4;
145
-	ts_packet[start + 0]  = tdt->pointer_field;
146
-	start += tdt->pointer_field + 1;
110
+	secdata[curpos + 0]  = (tdt->mjd &~ 0x00ff) >> 8;
111
+	secdata[curpos + 1]  = (tdt->mjd &~ 0xff00);
147 112
 
148
-	ts_packet[start + 0]  = tdt->table_id;
149
-	ts_packet[start + 1]  = tdt->section_syntax_indicator << 7;		// x1111111
150
-	ts_packet[start + 1] |= tdt->reserved_1               << 6;		// 1x111111
151
-	ts_packet[start + 1] |= tdt->reserved_2               << 4;		// 11xx1111
152
-	ts_packet[start + 1] |= tdt->section_length           >> 8;		// 1111xxxx xxxxxxxx
153
-	ts_packet[start + 2]  = tdt->section_length           &~ 0xff00;	// 1111xxxx xxxxxxxx
113
+	secdata[curpos + 2]  = (tdt->bcd >> 16);
114
+	secdata[curpos + 3]  = (tdt->bcd >> 8) &~ 0xff00;
115
+	secdata[curpos + 4]  = (tdt->bcd << 16) >> 16;
116
+	curpos += 5; // For the fields above
154 117
 
155
-	ts_packet[start + 3]  = (tdt->mjd &~ 0x00ff) >> 8;
156
-	ts_packet[start + 4]  = (tdt->mjd &~ 0xff00);
118
+	if (tdt->section_header->table_id == 0x73) { // TOT
119
+		secdata[curpos + 0]  = tdt->reserved_3 << 4;
120
+		secdata[curpos + 0] |= tdt->descriptors_size >> 8;
121
+		secdata[curpos + 1]  = tdt->descriptors_size &~ 0xf00;
122
+		curpos += 2;
157 123
 
158
-	ts_packet[start + 5]  = (tdt->bcd >> 16);
159
-	ts_packet[start + 6]  = (tdt->bcd >> 8) &~ 0xff00;
160
-	ts_packet[start + 7]  = (tdt->bcd << 16) >> 16;
161
-
162
-	if (tdt->table_id == 0x73) { // TOT
163
-		ts_packet[start + 8]  = tdt->reserved_3 << 4;
164
-		ts_packet[start + 8] |= tdt->descriptors_size >> 8;
165
-		ts_packet[start + 9]  = tdt->descriptors_size &~ 0xf00;
166
-		if (tdt->descriptors_size) {
167
-			memcpy(&ts_packet[start + 10], tdt->descriptors, tdt->descriptors_size);
124
+		if (tdt->descriptors_size > 0) {
125
+			memcpy(secdata + curpos, tdt->descriptors, tdt->descriptors_size);
126
+			curpos += tdt->descriptors_size;
168 127
 		}
169
-		tdt->CRC = ts_section_data_calculate_crc(ts_packet + start, 10 + tdt->descriptors_size);
128
+
129
+		tdt->section_header->CRC = ts_section_data_calculate_crc(secdata, curpos);
130
+	    curpos += 4; // CRC
170 131
 	}
132
+
133
+    ts_section_data_gen_ts_packets(&tdt->ts_header, secdata, curpos, tdt->section_header->pointer_field, ts_packets, num_packets);
134
+
135
+    FREE(secdata);
136
+}
137
+
138
+void ts_tdt_check_generator(struct ts_tdt *tdt) {
139
+	struct ts_tdt *tdt1 = ts_tdt_alloc();
140
+	int i;
141
+
142
+	char *prefix1 = "TDT (tspacket->struct)";
143
+	char *prefix2 = "TDT (struct->tspacket)";
144
+	if (tdt->section_header->table_id == 0x73) {
145
+		prefix1[1] = 'O';
146
+		prefix2[1] = 'O';
147
+	}
148
+
149
+	for (i=0;i<tdt->section_header->num_packets;i++) {
150
+		tdt1 = ts_tdt_push_packet(tdt1, tdt->section_header->packet_data + (i * TS_PACKET_SIZE));
151
+	}
152
+
153
+	ts_compare_data(prefix1, // "TDT (tspacket->struct)",
154
+		tdt1->section_header->packet_data,
155
+		tdt->section_header->packet_data,
156
+		tdt->section_header->num_packets * TS_PACKET_SIZE);
157
+	ts_tdt_free(&tdt1);
158
+
159
+	uint8_t *ts_packets;
160
+	int num_packets;
161
+	ts_tdt_generate(tdt, &ts_packets, &num_packets);
162
+	if (num_packets != tdt->section_header->num_packets) {
163
+		ts_LOGf("ERROR: num_packets:%d != sec->num_packets:%d\n", num_packets, tdt->section_header->num_packets);
164
+	}
165
+	ts_compare_data(prefix2 /* "TDT (struct->tspacket)" */, tdt->section_header->packet_data, ts_packets, num_packets * TS_PACKET_SIZE);
166
+
167
+	free(ts_packets);
171 168
 }
172 169
 
173 170
 void ts_tdt_dump(struct ts_tdt *tdt) {
171
+	struct ts_section_header *sec = tdt->section_header;
174 172
 	struct tm tm;
175 173
 	time_t ts;
176 174
 	uint16_t mjd_check;
177 175
 	uint32_t bcd_check;
178
-	char *prefix = tdt->table_id == 0x70 ? "TDT" : "TOT"; // TDT table_id == 0x70, TOT table_id == 0x73
176
+
177
+	ts_section_dump(sec);
179 178
 
180 179
 	ts = ts_time_decode_mjd(tdt->mjd, tdt->bcd, &tm);
181 180
 	ts_time_encode_mjd(&mjd_check, &bcd_check, &ts, &tm);
182 181
 
183
-	ts_LOGf("%s packet dump\n", prefix);
184
-	ts_packet_header_dump(&tdt->ts_header);
185
-	ts_LOGf("    - Table id           : %03x (%d) %s\n", tdt->table_id, tdt->table_id, prefix);
186
-	ts_LOGf("    - Section length     : %03x (%d)\n", tdt->section_length, tdt->section_length);
187
-	ts_LOGf("  * %s data\n", prefix);
182
+	ts_LOGf("  * %s data\n", sec->table_id == 0x70 ? "TDT" : "TOT");
188 183
 	ts_LOGf("    - MJD                : 0x%04x   (%04d-%02d-%02d) unixts: %ld check:0x%04x\n",
189 184
 		tdt->mjd,
190 185
 		tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
@@ -193,132 +188,12 @@ void ts_tdt_dump(struct ts_tdt *tdt) {
193 188
 		tdt->bcd,
194 189
 		tm.tm_hour, tm.tm_min, tm.tm_sec,
195 190
 		bcd_check);
196
-	ts_LOGf("    - UTC Time           : %lu\n" , tdt->utc);
197
-	if (tdt->table_id == 0x73) { // TOT
198
-		if (tdt->descriptors) {
199
-			ts_descriptor_dump(tdt->descriptors, tdt->descriptors_size);
200
-		}
201
-		ts_LOGf("  * CRC 0x%04x\n", tdt->CRC);
191
+	ts_LOGf("    - UTC Time           : %lu (%04d-%02d-%02d %02d:%02d:%02d)\n" , tdt->utc,
192
+		tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
193
+		tm.tm_hour, tm.tm_min, tm.tm_sec);
194
+	if (sec->table_id == 0x73 && tdt->descriptors_size) { // TOT
195
+		ts_descriptor_dump(tdt->descriptors, tdt->descriptors_size);
202 196
 	}
203 197
 
204 198
 	ts_tdt_check_generator(tdt);
205 199
 }
206
-
207
-void ts_tdt_set_time(struct ts_tdt *tdt, time_t now) {
208
-	tdt->ts_header.continuity++;
209
-	ts_time_encode_mjd(&tdt->mjd, &tdt->bcd, &now, NULL);
210
-	tdt->utc = ts_time_decode_mjd(tdt->mjd, tdt->bcd, &tdt->tm);
211
-	ts_tdt_generate(tdt, tdt->packet_data);
212
-}
213
-
214
-void ts_tot_set_localtime_offset(struct ts_tdt *tdt, time_t now, time_t change_time, uint8_t polarity, uint16_t ofs, uint16_t ofs_next) {
215
-	if (tdt->table_id != 0x73)
216
-		return;
217
-	tdt->ts_header.continuity++;
218
-
219
-	ts_time_encode_mjd(&tdt->mjd, &tdt->bcd, &now, NULL);
220
-	tdt->utc = ts_time_decode_mjd(tdt->mjd, tdt->bcd, &tdt->tm);
221
-
222
-	uint16_t mjd = 0;
223
-	uint32_t bcd = 0;
224
-	ts_time_encode_mjd(&mjd, &bcd, &change_time, NULL);
225
-
226
-	uint8_t *lto; // Local time offset
227
-	if (tdt->descriptors_size == 0) {
228
-		tdt->descriptors_size = 15;
229
-		tdt->descriptors = calloc(1, tdt->descriptors_size);
230
-		tdt->section_length += tdt->descriptors_size;
231
-	}
232
-	lto = tdt->descriptors;
233
-	lto[0     ]  = 0x58;		// Descriptor tag
234
-	lto[1     ]  = 13;			// 13 octets
235
-	lto[2 +  0]  = 'B';			// Country code
236
-	lto[2 +  1]  = 'U';
237
-	lto[2 +  2]  = 'L';
238
-	lto[2 +  3]  = 0;			// 111111xx (Country region,   6 bit)
239
-	lto[2 +  3] |= bit_2;		// xxxxxx1x (Reserved,         1 bit) !!!!
240
-	lto[2 +  3] |= polarity;	// xxxxxxx1 (Polarity,         1 bit, 0 +utc, 1 -utc) !!!!
241
-
242
-	lto[2 +  4]  = ofs >> 8;	// (LocalTime offset  16 bits, bcd)
243
-	lto[2 +  5]  = ofs &~ 0xff00;
244
-
245
-	lto[2 +  6]  = mjd >> 8;	// Time of change (40 bcd)
246
-	lto[2 +  7]  = mjd &~ 0xff00;
247
-	lto[2 +  8]  = bcd >> 16;
248
-	lto[2 +  9]  = bcd >> 8;
249
-	lto[2 + 10]  = bcd &~ 0xffff00;
250
-
251
-	lto[2 + 11]  = ofs_next >> 8; // Next time offset (16 bits, bcd)
252
-	lto[2 + 12]  = ofs_next &~ 0xff00;
253
-
254
-	ts_tdt_generate(tdt, tdt->packet_data);
255
-}
256
-
257
-// Calculate change time for European summer time, see:
258
-// http://en.wikipedia.org/wiki/European_Summer_Time
259
-static time_t euro_dst_start(int year) {
260
-	struct tm tm;
261
-	int dst_start_date;
262
-	memset(&tm, 0, sizeof(struct tm));
263
-	tm.tm_year = year - 1900;
264
-	tm.tm_mon  = 2; // March
265
-	tm.tm_mday = (31 - (5 * year / 4 + 4) % 7); // Sunday DST_START March   at 01:00 GMT
266
-	tm.tm_hour = 1;
267
-	dst_start_date = timegm(&tm);
268
-	//ts_LOGf("year: %d ts: %d dst_start: %s", year, dst_start_date, asctime(&tm));
269
-	return dst_start_date;
270
-}
271
-
272
-static time_t euro_dst_end(int year) {
273
-	struct tm tm;
274
-	int dst_end_date;
275
-	memset(&tm, 0, sizeof(struct tm));
276
-	tm.tm_year = year - 1900;
277
-	tm.tm_mon  = 9; // October
278
-	tm.tm_mday = (31 - (5 * year / 4 + 1) % 7); // Sunday DST_END   October at 01:00 GMT
279
-	tm.tm_hour = 1;
280
-	dst_end_date = timegm(&tm);
281
-	//ts_LOGf("year: %d ts: %d dst_end: %s", year, dst_end_date, asctime(&tm));
282
-	return dst_end_date;
283
-}
284
-
285
-void ts_tot_set_localtime_offset_sofia(struct ts_tdt *tdt) {
286
-	time_t   now = time(NULL);
287
-	uint8_t  polarity = 0;	// 0 == UTC + offset, 1 == UTC - offset
288
-	time_t   change_time;	// When the next DST change will be
289
-	uint16_t current_offset;
290
-	uint16_t next_offset;
291
-	struct tm tm;
292
-
293
-	gmtime_r(&now, &tm);
294
-	//ts_LOGf("nowts: %d now: %s", now, asctime(&tm));
295
-	int curyear  = tm.tm_year + 1900;
296
-	int dst_start_date = euro_dst_start(curyear);
297
-	int dst_end_date   = euro_dst_end(curyear);
298
-	if (now < dst_start_date) {
299
-		current_offset = 0x0200; // We are in winter time now
300
-		next_offset    = 0x0300; // Next is the summer
301
-		change_time    = dst_start_date;
302
-	} else {
303
-		if (now >= dst_start_date && now < dst_end_date) {
304
-			current_offset = 0x0300; // We are in summer time time
305
-			next_offset    = 0x0200; // Next time it should be winter
306
-			change_time    = dst_end_date;
307
-		} else {
308
-			current_offset = 0x0200; // We are in winter time
309
-			next_offset    = 0x0300; // Next time it should be summer
310
-			change_time    = euro_dst_start(curyear + 1);
311
-		}
312
-	}
313
-	//ts_LOGf("curofs: %04x next_ofs: %04x change_time:%d\n", current_offset, next_offset, change_time);
314
-	ts_tot_set_localtime_offset(tdt, time(NULL), change_time, polarity, current_offset, next_offset);
315
-}
316
-
317
-int parse_tdt(uint8_t *ts_packet, int dump) {
318
-	struct ts_tdt *tdt = ts_tdt_alloc();
319
-	int ret = ts_tdt_parse(tdt, ts_packet);
320
-	if (ret && dump)
321
-		ts_tdt_dump(tdt);
322
-	ts_tdt_free(&tdt);
323
-	return ret;
324
-}

+ 160
- 0
tsfuncs_tdt_desc.c View File

@@ -0,0 +1,160 @@
1
+#include <stdio.h>
2
+#include <unistd.h>
3
+#include <netdb.h>
4
+#include <stdlib.h>
5
+#include <string.h>
6
+#include <time.h>
7
+
8
+#include "tsfuncs.h"
9
+
10
+static void ts_tdt_regenerate_packet_data(struct ts_tdt *tdt) {
11
+	uint8_t *ts_packets;
12
+	int num_packets;
13
+	ts_tdt_generate(tdt, &ts_packets, &num_packets);
14
+	memcpy(tdt->section_header->packet_data, ts_packets, num_packets * TS_PACKET_SIZE);
15
+	tdt->section_header->num_packets = num_packets;
16
+	free(ts_packets);
17
+}
18
+
19
+static struct ts_tdt *ts_tdt_init_empty(struct ts_tdt *tdt, time_t ts, int tot) {
20
+	tdt->ts_header.pid            = 0x14;
21
+	tdt->ts_header.pusi           = 1;
22
+	tdt->ts_header.payload_field  = 1;
23
+	tdt->ts_header.payload_offset = 4;
24
+
25
+	tdt->section_header->table_id                 = 0x70;
26
+	tdt->section_header->section_syntax_indicator = 0;
27
+	tdt->section_header->private_indicator        = 1;
28
+	tdt->section_header->reserved1                = 3;
29
+	tdt->section_header->section_length           = 5; // 5 bytes UTC_time
30
+
31
+	ts_time_encode_mjd(&tdt->mjd, &tdt->bcd, &ts, NULL);
32
+	tdt->utc = ts_time_decode_mjd(tdt->mjd, tdt->bcd, &tdt->tm);
33
+
34
+	if (tot) {
35
+		tdt->section_header->table_id             = 0x73;
36
+		tdt->section_header->section_length       = 5 + 2 + 4;	// 5 bytes UTC_time, 2 bytes reserved & descripts_size, 4 bytes CRC
37
+		tdt->reserved_3           = 0xf;
38
+		tdt->descriptors_size     = 0;
39
+	}
40
+
41
+	tdt->initialized = 1;
42
+	ts_tdt_regenerate_packet_data(tdt);
43
+
44
+	return tdt;
45
+}
46
+
47
+struct ts_tdt *ts_tdt_alloc_init(time_t ts) {
48
+	return ts_tdt_init_empty(ts_tdt_alloc(), ts, 0);
49
+}
50
+
51
+struct ts_tdt *ts_tot_alloc_init(time_t ts) {
52
+	return ts_tdt_init_empty(ts_tdt_alloc(), ts, 1);
53
+}
54
+
55
+void ts_tdt_set_time(struct ts_tdt *tdt, time_t now) {
56
+	ts_time_encode_mjd(&tdt->mjd, &tdt->bcd, &now, NULL);
57
+	tdt->utc = ts_time_decode_mjd(tdt->mjd, tdt->bcd, &tdt->tm);
58
+	ts_tdt_regenerate_packet_data(tdt);
59
+}
60
+
61
+void ts_tot_set_localtime_offset(struct ts_tdt *tdt, time_t now, time_t change_time, uint8_t polarity, uint16_t ofs, uint16_t ofs_next) {
62
+	if (tdt->section_header->table_id != 0x73)
63
+		return;
64
+
65
+	ts_time_encode_mjd(&tdt->mjd, &tdt->bcd, &now, NULL);
66
+	tdt->utc = ts_time_decode_mjd(tdt->mjd, tdt->bcd, &tdt->tm);
67
+
68
+	uint16_t mjd = 0;
69
+	uint32_t bcd = 0;
70
+	ts_time_encode_mjd(&mjd, &bcd, &change_time, NULL);
71
+
72
+	uint8_t *lto; // Local time offset
73
+	if (tdt->descriptors_size == 0) {
74
+		tdt->descriptors_size = 15;
75
+		tdt->descriptors = calloc(1, tdt->descriptors_size);
76
+		tdt->section_header->section_length += tdt->descriptors_size;
77
+	}
78
+	lto = tdt->descriptors;
79
+	lto[0     ]  = 0x58;		// Descriptor tag
80
+	lto[1     ]  = 13;			// 13 octets
81
+	lto[2 +  0]  = 'B';			// Country code
82
+	lto[2 +  1]  = 'U';
83
+	lto[2 +  2]  = 'L';
84
+	lto[2 +  3]  = 0;			// 111111xx (Country region,   6 bit)
85
+	lto[2 +  3] |= bit_2;		// xxxxxx1x (Reserved,         1 bit) !!!!
86
+	lto[2 +  3] |= polarity;	// xxxxxxx1 (Polarity,         1 bit, 0 +utc, 1 -utc) !!!!
87
+
88
+	lto[2 +  4]  = ofs >> 8;	// (LocalTime offset  16 bits, bcd)
89
+	lto[2 +  5]  = ofs &~ 0xff00;
90
+
91
+	lto[2 +  6]  = mjd >> 8;	// Time of change (40 bcd)
92
+	lto[2 +  7]  = mjd &~ 0xff00;
93
+	lto[2 +  8]  = bcd >> 16;
94
+	lto[2 +  9]  = bcd >> 8;
95
+	lto[2 + 10]  = bcd &~ 0xffff00;
96
+
97
+	lto[2 + 11]  = ofs_next >> 8; // Next time offset (16 bits, bcd)
98
+	lto[2 + 12]  = ofs_next &~ 0xff00;
99
+
100
+	ts_tdt_regenerate_packet_data(tdt);
101
+}
102
+
103
+// Calculate change time for European summer time, see:
104
+// http://en.wikipedia.org/wiki/European_Summer_Time
105
+static time_t euro_dst_start(int year) {
106
+	struct tm tm;
107
+	int dst_start_date;
108
+	memset(&tm, 0, sizeof(struct tm));
109
+	tm.tm_year = year - 1900;
110
+	tm.tm_mon  = 2; // March
111
+	tm.tm_mday = (31 - (5 * year / 4 + 4) % 7); // Sunday DST_START March   at 01:00 GMT
112
+	tm.tm_hour = 1;
113
+	dst_start_date = timegm(&tm);
114
+	//ts_LOGf("year: %d ts: %d dst_start: %s", year, dst_start_date, asctime(&tm));
115
+	return dst_start_date;
116
+}
117
+
118
+static time_t euro_dst_end(int year) {
119
+	struct tm tm;
120
+	int dst_end_date;
121
+	memset(&tm, 0, sizeof(struct tm));
122
+	tm.tm_year = year - 1900;
123
+	tm.tm_mon  = 9; // October
124
+	tm.tm_mday = (31 - (5 * year / 4 + 1) % 7); // Sunday DST_END   October at 01:00 GMT
125
+	tm.tm_hour = 1;
126
+	dst_end_date = timegm(&tm);
127
+	//ts_LOGf("year: %d ts: %d dst_end: %s", year, dst_end_date, asctime(&tm));
128
+	return dst_end_date;
129
+}
130
+
131
+void ts_tot_set_localtime_offset_sofia(struct ts_tdt *tdt, time_t now) {
132
+	uint8_t  polarity = 0;	// 0 == UTC + offset, 1 == UTC - offset
133
+	time_t   change_time;	// When the next DST change will be
134
+	uint16_t current_offset;
135
+	uint16_t next_offset;
136
+	struct tm tm;
137
+
138
+	gmtime_r(&now, &tm);
139
+	//ts_LOGf("nowts: %d now: %s", now, asctime(&tm));
140
+	int curyear  = tm.tm_year + 1900;
141
+	int dst_start_date = euro_dst_start(curyear);
142
+	int dst_end_date   = euro_dst_end(curyear);
143
+	if (now < dst_start_date) {
144
+		current_offset = 0x0200; // We are in winter time now
145
+		next_offset    = 0x0300; // Next is the summer
146
+		change_time    = dst_start_date;
147
+	} else {
148
+		if (now >= dst_start_date && now < dst_end_date) {
149
+			current_offset = 0x0300; // We are in summer time time
150
+			next_offset    = 0x0200; // Next time it should be winter
151
+			change_time    = dst_end_date;
152
+		} else {
153
+			current_offset = 0x0200; // We are in winter time
154
+			next_offset    = 0x0300; // Next time it should be summer
155
+			change_time    = euro_dst_start(curyear + 1);
156
+		}
157
+	}
158
+	//ts_LOGf("curofs: %04x next_ofs: %04x change_time:%d\n", current_offset, next_offset, change_time);
159
+	ts_tot_set_localtime_offset(tdt, now, change_time, polarity, current_offset, next_offset);
160
+}

Loading…
Cancel
Save