1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <ctype.h>
6 #include <sys/errno.h>
7 #include "emulate.h"
8
9 #include "dump-vdr.h" // debugging transponder.
10 #include "dump-xine.h" // debugging transponder.
11 #include "dvbscan.h" // debugging transponder.
12 #include "tools.h" // hexdump
13
14 #define Hz 1
15 #define kHz (1000 * Hz)
16 #define MHz (1000 * kHz)
17
18 //#define EM_INFO(msg...) info(msg)
19 #define EM_INFO(msg...)
20
21 /* this struct stores the contents (DVB SI data) of an section buffer,
22 * alltogether with the current tuning state of the dvb device.
23 */
24 typedef struct {
25 /*----------------------------*/
26 void *prev;
27 void *next;
28 uint32_t index;
29 /*----------------------------*/
30 uint16_t pid;
31 uint16_t table_id;
32 uint16_t table_id_ext;
33 uint16_t original_network_id;
34 uint16_t network_id;
35 uint16_t transport_stream_id;
36 uint16_t service_id;
37 uint16_t len;
38 struct transponder t;
39 unsigned char buf[SECTION_BUF_SIZE];
40 } sidata_t;
41
42 /*
43 * list of DVB SI data and list of running demux filters.
44 */
45 cList __em_buf1, *em_runningfilters = &__em_buf1;
46 cList __em_buf2, *em_sidata = &__em_buf2;
47
48 /*
49 * drivers DVB API.
50 * NOTE:
51 * - API defaults to 5.3
52 * - if not overwritten from log -> bug.
53 */
54 struct {
55 unsigned major;
56 unsigned minor;
57 } em_api = {
58 5, 3};
59
60 /*
61 * The emulated DVB device.
62 * NOTE:
63 * - state is set by em_setproperty and returned by em_getproperty
64 * - not to be exposed outside this file.
65 */
66 static struct {
67 unsigned w_scan_version;
68 uint32_t w_scan_flags;
69 fe_delivery_system_t delsys;
70 uint32_t frequency;
71 uint32_t bandwidth_hz;
72 uint32_t symbolrate;
73 uint8_t stream_id;
74 fe_spectral_inversion_t inversion;
75 fe_modulation_t modulation;
76 fe_code_rate_t fec;
77 fe_pilot_t pilot;
78 fe_rolloff_t rolloff;
79 fe_transmit_mode_t transmission;
80 fe_guard_interval_t guard;
81 fe_hierarchy_t hierarchy;
82 fe_polarization_t polarization;
83 struct dvb_frontend_info fe_info;
84 fe_delivery_system_t delsystems[32];
85 uint8_t ndelsystems;
86 scantype_t scantype;
87 bool T2_delsys_bug;
88 bool highband;
89 uint32_t lnb_low;
90 uint32_t lnb_high;
91 } em_device;
92
93 #define EM_OLD_DELSYSLIST (((uint32_t)1) << 1)
94 #define EM_OLD_APIDISP (((uint32_t)1) << 2)
95 #define EM_HEXDUMP_BUG (((uint32_t)1) << 3)
96 #define EM_OLD_SI_HEADER (((uint32_t)1) << 4)
97
98 /*
99 * forward declarations.
100 */
101 static int parse_logfile(const char *log);
102
103 // Declare parse_xyz in scan.h? Hmm..
104 extern void parse_pat(const unsigned char *buf, uint16_t section_length,
105 uint16_t transport_stream_id, uint32_t flags);
106 extern void parse_pmt(const unsigned char *buf, uint16_t section_length,
107 uint16_t service_id);
108 extern void parse_nit(const unsigned char *buf, uint16_t section_length,
109 uint8_t table_id, uint16_t network_id,
110 uint32_t section_flags);
111 extern void parse_sdt(const unsigned char *buf, uint16_t section_length,
112 uint16_t transport_stream_id);
113 extern void parse_psip_vct(const unsigned char *buf, uint16_t section_length,
114 uint8_t table_id, uint16_t transport_stream_id);
115
116 /*
117 * initializes emulated dvb device and fills in data by parsing logfile.
118 */
em_init(const char * log)119 void em_init(const char *log)
120 {
121 NewList(em_runningfilters, "em_runningfilters");
122 NewList(em_sidata, "em_sidata");
123 memset(&em_device, 0, sizeof(em_device));
124 parse_logfile(log);
125 }
126
127 /*
128 * let 'frontend_fd' be any non-negative int to pass validity checks.
129 */
em_open(int * frontend_fd)130 void em_open(int *frontend_fd)
131 {
132 *frontend_fd = 1;
133 }
134
135 /*
136 * replaces FE_GET_INFO ioctl.
137 */
em_info(struct dvb_frontend_info * fe_info)138 void em_info(struct dvb_frontend_info *fe_info)
139 {
140 memcpy(fe_info, &em_device.fe_info, sizeof(struct dvb_frontend_info));
141 }
142
143 /*
144 * replaces DTV_API_VERSION ioctl.
145 */
em_dvbapi(uint16_t * flags)146 void em_dvbapi(uint16_t * flags)
147 {
148 *flags = (em_api.major << 8) | em_api.minor;
149 }
150
151 /*
152 * replaces FE_SET_PROPERTY ioctl.
153 */
em_setproperty(struct dtv_properties * cmdseq)154 int em_setproperty(struct dtv_properties *cmdseq)
155 {
156 uint8_t i;
157 for (i = 0; i < cmdseq->num; i++) {
158 switch (cmdseq->props[i].cmd) {
159 case DTV_DELIVERY_SYSTEM:
160 em_device.delsys = cmdseq->props[i].u.data;
161 break;
162 case DTV_FREQUENCY:
163 em_device.frequency = cmdseq->props[i].u.data;
164 break;
165 case DTV_INVERSION:
166 em_device.inversion = cmdseq->props[i].u.data;
167 break;
168 case DTV_MODULATION:
169 em_device.modulation = cmdseq->props[i].u.data;
170 break;
171 case DTV_SYMBOL_RATE:
172 em_device.symbolrate = cmdseq->props[i].u.data;
173 break;
174 case DTV_INNER_FEC:
175 em_device.fec = cmdseq->props[i].u.data;
176 break;
177 case DTV_PILOT:
178 em_device.pilot = cmdseq->props[i].u.data;
179 break;
180 case DTV_ROLLOFF:
181 em_device.rolloff = cmdseq->props[i].u.data;
182 break;
183 case DTV_STREAM_ID:
184 em_device.stream_id = cmdseq->props[i].u.data;
185 break;
186 case DTV_BANDWIDTH_HZ:
187 em_device.bandwidth_hz = cmdseq->props[i].u.data;
188 break;
189 case DTV_CODE_RATE_HP:
190 em_device.fec = cmdseq->props[i].u.data;
191 break;
192 case DTV_TRANSMISSION_MODE:
193 em_device.transmission = cmdseq->props[i].u.data;
194 break;
195 case DTV_GUARD_INTERVAL:
196 em_device.guard = cmdseq->props[i].u.data;
197 break;
198 case DTV_HIERARCHY:
199 em_device.hierarchy = cmdseq->props[i].u.data;
200 break;
201 case DTV_CLEAR:
202 break; // what to do with clear?
203 default:;
204 }
205 }
206 return 0; // no err.
207 }
208
209 /*
210 * replaces FE_GET_PROPERTY ioctl.
211 */
em_getproperty(struct dtv_properties * cmdseq)212 int em_getproperty(struct dtv_properties *cmdseq)
213 {
214 uint8_t i;
215 int j, k;
216 for (i = 0; i < cmdseq->num; i++) {
217 switch (cmdseq->props[i].cmd) {
218 case DTV_DELIVERY_SYSTEM:
219 cmdseq->props[i].u.data = em_device.delsys;
220 break;
221 case DTV_FREQUENCY:
222 cmdseq->props[i].u.data = em_device.frequency;
223 break;
224 case DTV_INVERSION:
225 cmdseq->props[i].u.data = em_device.inversion;
226 break;
227 case DTV_MODULATION:
228 cmdseq->props[i].u.data = em_device.modulation;
229 break;
230 case DTV_SYMBOL_RATE:
231 cmdseq->props[i].u.data = em_device.symbolrate;
232 break;
233 case DTV_INNER_FEC:
234 cmdseq->props[i].u.data = em_device.fec;
235 break;
236 case DTV_PILOT:
237 cmdseq->props[i].u.data = em_device.pilot;
238 break;
239 case DTV_ROLLOFF:
240 cmdseq->props[i].u.data = em_device.rolloff;
241 break;
242 case DTV_STREAM_ID:
243 cmdseq->props[i].u.data = em_device.stream_id;
244 break;
245 case DTV_BANDWIDTH_HZ:
246 cmdseq->props[i].u.data = em_device.bandwidth_hz;
247 break;
248 case DTV_CODE_RATE_HP:
249 cmdseq->props[i].u.data = em_device.fec;
250 break;
251 case DTV_TRANSMISSION_MODE:
252 cmdseq->props[i].u.data = em_device.transmission;
253 break;
254 case DTV_GUARD_INTERVAL:
255 cmdseq->props[i].u.data = em_device.guard;
256 break;
257 case DTV_HIERARCHY:
258 cmdseq->props[i].u.data = em_device.hierarchy;
259 break;
260 case DTV_ENUM_DELSYS:
261 cmdseq->props[i].u.buffer.len = em_device.ndelsystems;
262 for (j = 0, k = em_device.ndelsystems - 1;
263 j < em_device.ndelsystems; j++, k--)
264 cmdseq->props[i].u.buffer.data[k] =
265 em_device.delsystems[j];
266 break;
267 default:;
268 }
269 }
270 return 0; // no err.
271 }
272
em_lnb(int high_band,uint32_t high_val,uint32_t low_val)273 void em_lnb(int high_band, uint32_t high_val, uint32_t low_val)
274 {
275 em_device.highband = high_band;
276 em_device.lnb_low = low_val;
277 em_device.lnb_high = high_val;
278 }
279
em_polarization(uint8_t p)280 void em_polarization(uint8_t p)
281 {
282 em_device.polarization = p & 0x3;
283 }
284
285 /*
286 * INTERNAL USE ONLY. DONT EXPOSE THIS FUNC OUTSIDE THIS FILE.
287 */
has_lock(fe_delivery_system_t em_delsys,struct transponder * t)288 static int has_lock(fe_delivery_system_t em_delsys, struct transponder *t)
289 {
290 uint32_t tp_if = 0;
291
292 switch (em_delsys) {
293 case SYS_DVBT:
294 case SYS_DVBT2:
295 if (t->frequency != em_device.frequency)
296 return 0;
297 EM_INFO("%s: f=%u B%uC%dD0M%dT%dG%dY%dS%d\n"
298 " f=%u B%dC%dD0M%dT%dG%dY%dS%d\n",
299 __FUNCTION__,
300 freq_scale(em_device.frequency, 1e-3),
301 freq_scale(em_device.bandwidth_hz, 1e-6), em_device.fec,
302 em_device.modulation, em_device.transmission,
303 em_device.guard, em_device.hierarchy,
304 em_device.delsys == SYS_DVBT2, freq_scale(t->frequency,
305 1e-3),
306 freq_scale(t->bandwidth, 1e-6), t->coderate,
307 t->modulation, t->transmission, t->guard, t->hierarchy,
308 t->delsys == SYS_DVBT2);
309 if (t->bandwidth != em_device.bandwidth_hz)
310 return 0;
311 if ((t->coderate != em_device.fec) && (t->coderate != FEC_AUTO))
312 return 0;
313 if ((t->modulation != em_device.modulation)
314 && (t->modulation != QAM_AUTO))
315 return 0;
316 if ((t->transmission != em_device.transmission)
317 && (t->transmission != TRANSMISSION_MODE_AUTO))
318 return 0;
319 if ((t->guard != em_device.guard)
320 && (t->guard != GUARD_INTERVAL_AUTO))
321 return 0;
322 if ((t->hierarchy != em_device.hierarchy)
323 && (t->hierarchy != HIERARCHY_AUTO))
324 return 0;
325 if (!em_device.T2_delsys_bug) {
326 // any dvb driver here, except CXD2820R
327 if (t->delsys != em_device.delsys)
328 return 0;
329 } else {
330 // CXD2820R only: driver silently changes delsys.
331 em_device.delsys = t->delsys;
332 }
333 return 0x1F;
334 break;
335 case SYS_DVBC_ANNEX_A:
336 case SYS_DVBC_ANNEX_C:
337 if (t->frequency != em_device.frequency)
338 return 0;
339 if ((t->delsys != SYS_DVBC_ANNEX_A)
340 && (t->delsys != SYS_DVBC_ANNEX_C))
341 return 0;
342 if ((t->modulation != em_device.modulation)
343 && (em_device.modulation != QAM_AUTO))
344 return 0;
345 if (t->symbolrate != em_device.symbolrate)
346 return 0;
347 return 0x1F;
348 break;
349 case SYS_DVBS2:
350 if ((t->rolloff != em_device.rolloff)
351 && (em_device.rolloff != ROLLOFF_35)
352 && (em_device.rolloff != ROLLOFF_AUTO)) {
353 EM_INFO("wrong rolloff: %d != %d\n", t->rolloff,
354 em_device.rolloff);
355 return 0;
356 }
357 if ((t->pilot != em_device.pilot)
358 && (em_device.pilot != PILOT_AUTO)) {
359 EM_INFO("wrong pilot: %d != %d\n", t->pilot,
360 em_device.pilot);
361 return 0;
362 }
363 /* fall trough. */
364 case SYS_DVBS:
365 if (em_device.highband)
366 tp_if = abs(t->frequency - em_device.lnb_high);
367 else
368 tp_if = abs(t->frequency - em_device.lnb_low);
369
370 if (abs(tp_if - em_device.frequency) > 2000) {
371 EM_INFO
372 ("t->frequency = %u: tp_if = %u <-> em_device.frequency = %u\n",
373 t->frequency, tp_if, em_device.frequency);
374 return 0;
375 }
376 if (t->delsys != em_device.delsys) {
377 EM_INFO("wrong delsys\n");
378 return 0;
379 }
380 if (t->polarization != em_device.polarization) {
381 EM_INFO("wrong polarization\n");
382 return 0;
383 }
384 if ((t->coderate != em_device.fec)
385 && (em_device.fec != FEC_AUTO)) {
386 EM_INFO("wrong coderate\n");
387 return 0;
388 }
389 if (t->symbolrate != em_device.symbolrate) {
390 EM_INFO("wrong symbolrate\n");
391 return 0;
392 }
393 if (t->modulation != em_device.modulation) {
394 EM_INFO("wrong modulation\n");
395 return 0;
396 }
397 return 0x1F;
398 break;
399 case SYS_ATSC:
400 if (t->frequency != em_device.frequency)
401 return 0;
402 if (t->delsys != em_device.delsys)
403 return 0;
404 if (t->modulation != em_device.modulation)
405 return 0;
406 return 0x1F;
407 break;
408 default:
409 fatal("unsupported del sys.\n");
410 }
411 return 0;
412 }
413
414 /*
415 * replaces FE_READ_STATUS ioctl.
416 */
em_status(fe_status_t * status)417 int em_status(fe_status_t * status)
418 {
419 sidata_t *s;
420
421 *status = 0;
422 for (s = em_sidata->first; s; s = s->next) {
423 //char b[256];
424 //print_transponder(b, &s->t);
425 //info("%s: try %s (current: %d lo %d highband=%d)\n",__FUNCTION__,b, em_device.frequency, em_device.highband?em_device.lnb_high:em_device.lnb_low, em_device.highband);
426 if (has_lock(em_device.delsys, &s->t)) {
427 *status = 0x1F; // sync && lock.
428 break;
429 }
430 }
431 return 0;
432 }
433
434 /*----------------------------------------------------------------------------------------------------------------------
435 * DEMUX related.
436 *---------------------------------------------------------------------------------------------------------------------*/
437
table_name(uint16_t id)438 static const char *table_name(uint16_t id)
439 {
440 switch (id) {
441 case TABLE_PAT:
442 return "PAT";
443 case TABLE_PMT:
444 return "PMT";
445 case TABLE_NIT_ACT:
446 return "NIT(ACT)";
447 case TABLE_NIT_OTH:
448 return "NIT(OTH)";
449 case TABLE_SDT_ACT:
450 return "SDT(ACT)";
451 case TABLE_SDT_OTH:
452 return "SDT(OTH)";
453 case TABLE_VCT_TERR:
454 return "VCT(TERR)";
455 case TABLE_VCT_CABLE:
456 return "VCT(CABLE)";
457 default:
458 return "???";
459 }
460 }
461
em_addfilter(struct section_buf * s)462 void em_addfilter(struct section_buf *s)
463 {
464 EM_INFO("%s: %s pid=%d\n", __FUNCTION__, table_name(s->table_id),
465 s->pid);
466 AddItem(em_runningfilters, s);
467 }
468
em_readfilters(int * result)469 void em_readfilters(int *result)
470 {
471 sidata_t *sidata;
472 struct section_buf *filter;
473 int maxiter = 10000;
474
475 while ((filter = em_runningfilters->first)) {
476 bool data_found = false;
477 if (!maxiter--)
478 fatal("%s: max iterations.\n", __FUNCTION__);
479 for (sidata = em_sidata->first; sidata; sidata = sidata->next) {
480 if (filter->table_id != sidata->table_id) {
481 // info("(filter->table_id = %d != table_id = %d), table_id_ext = %d, pid = %d\n", filter->table_id, sidata->table_id, sidata->table_id_ext, sidata->pid);
482 continue;
483 }
484 EM_INFO
485 ("f=%-6d: searching %-10s: table_id_ext = %d, pid = %d\n",
486 freq_scale(em_device.frequency, 1e-3),
487 table_name(filter->table_id), filter->table_id_ext,
488 filter->pid);
489
490 if (!has_lock(em_device.delsys, &sidata->t)) {
491 EM_INFO(" -> no lock @ %d\n",
492 freq_scale(sidata->t.frequency, 1e-3));
493 continue;
494 }
495
496 if ((filter->pid != sidata->pid)
497 && (filter->table_id == TABLE_PMT)) {
498 EM_INFO(" -> wrong pid %d\n", sidata->pid);
499 continue;
500 }
501
502 if ((filter->table_id_ext != sidata->table_id_ext)
503 && (filter->table_id_ext > -1)) {
504 EM_INFO(" -> wrong table_id_ext = %d\n",
505 sidata->table_id_ext);
506 continue;
507 }
508 EM_INFO(" -> OK.\n");
509 data_found = true;
510
511 switch (filter->table_id) {
512 case TABLE_PAT:
513 parse_pat(sidata->buf, sidata->len,
514 sidata->transport_stream_id,
515 filter->flags);
516 break;
517 case TABLE_NIT_ACT:
518 case TABLE_NIT_OTH:
519 parse_nit(sidata->buf, sidata->len,
520 filter->table_id, sidata->network_id,
521 filter->flags);
522 break;
523 case TABLE_PMT:
524 verbose
525 ("PMT %d (0x%04x) for service %d (0x%04x)\n",
526 sidata->pid, sidata->pid,
527 sidata->service_id, sidata->service_id);
528 parse_pmt(sidata->buf, sidata->len,
529 sidata->service_id);
530 break;
531 case TABLE_SDT_ACT:
532 case TABLE_SDT_OTH:
533 verbose
534 ("SDT(%s TS, transport_stream_id %d (0x%04x) )\n",
535 filter->table_id ==
536 0x42 ? "actual" : "other",
537 sidata->transport_stream_id,
538 sidata->transport_stream_id);
539 parse_sdt(sidata->buf, sidata->len,
540 sidata->transport_stream_id);
541 break;
542 case TABLE_VCT_TERR:
543 case TABLE_VCT_CABLE:
544 verbose
545 ("ATSC VCT, table_id %d, table_id_ext %d\n",
546 sidata->table_id, sidata->table_id_ext);
547 parse_psip_vct(sidata->buf, sidata->len,
548 filter->table_id,
549 sidata->table_id_ext);
550 break;
551 default:
552 fatal("%s %d: unhandled table_id %d\n",
553 __FUNCTION__, __LINE__, filter->table_id);
554 }
555 //if (filter->run_once) /* probably i would have to check version nums here. */
556 // break;
557 }
558
559 if (!data_found) {
560 const char *intro = " Info: no data from ";
561 // timeout waiting for data.
562 switch (filter->table_id) {
563 case TABLE_PAT:
564 case TABLE_PMT:
565 case TABLE_NIT_ACT:
566 case TABLE_NIT_OTH:
567 case TABLE_SDT_ACT:
568 case TABLE_SDT_OTH:
569 case TABLE_VCT_TERR:
570 case TABLE_VCT_CABLE:
571 info("%s%s after %lld seconds\n", intro,
572 table_name(filter->table_id),
573 (long long)filter->timeout);
574 break;
575 default:
576 info("%spid %u after %lld seconds\n", intro,
577 filter->pid, (long long)filter->timeout);
578 }
579 *result = 0;
580 }
581 UnlinkItem(em_runningfilters, filter,
582 filter->flags & SECTION_FLAG_FREE ? true : false);
583 }
584 *result = 1;
585 return;
586 }
587
parse_tp(const char * str)588 static int parse_tp(const char *str)
589 {
590 uint32_t args[8];
591 char mbuf[64], fecbuf[5], robuf[5];
592 char c;
593 char *p = strchr(str, '(');
594 if (p && *p)
595 *p = 0; // cut '(ONID:NID:SID)'
596
597 switch (em_device.scantype) {
598 case SCAN_TERRESTRIAL:
599 p = strchr(str, 'P');
600 if (p) {
601 em_device.delsys = SYS_DVBT2;
602 sscanf(p + 1, "%u", &args[0]);
603 em_device.stream_id = args[0];
604 } else {
605 em_device.delsys = SYS_DVBT;
606 em_device.stream_id = 0;
607 }
608 sscanf(str, "%8s f = %6d kHz I%uB%uC%uD%uT%uG%uY%u",
609 mbuf, &args[0], &args[1], &args[2], &args[3], &args[4],
610 &args[5], &args[6], &args[7]);
611
612 if (strncmp(mbuf, "QPSK", 4) == 0)
613 em_device.modulation = QPSK;
614 else if (strncmp(mbuf, "QAM_16", 6) == 0)
615 em_device.modulation = QAM_16;
616 else if (strncmp(mbuf, "QAM_64", 6) == 0)
617 em_device.modulation = QAM_64;
618 else if (strncmp(mbuf, "QAM_256", 7) == 0)
619 em_device.modulation = QAM_256;
620 else
621 em_device.modulation = QAM_AUTO;
622 em_device.frequency = 1000 * args[0];
623 switch (args[1]) {
624 case 0:
625 em_device.inversion = INVERSION_OFF;
626 break;
627 case 1:
628 em_device.inversion = INVERSION_ON;
629 break;
630 default:
631 em_device.inversion = INVERSION_AUTO;
632 }
633 switch (args[2]) {
634 case 5 ... 10:
635 em_device.bandwidth_hz = args[2] * MHz;
636 break;
637 case 1712:
638 em_device.bandwidth_hz = args[2] * kHz;
639 break;
640 default:
641 em_device.bandwidth_hz = 8 * MHz;
642 }
643 switch (args[3]) {
644 case 0:
645 em_device.fec = FEC_NONE;
646 break;
647 case 12:
648 em_device.fec = FEC_1_2;
649 break;
650 case 23:
651 em_device.fec = FEC_2_3;
652 break;
653 case 34:
654 em_device.fec = FEC_3_4;
655 break;
656 case 45:
657 em_device.fec = FEC_4_5;
658 break;
659 case 56:
660 em_device.fec = FEC_5_6;
661 break;
662 case 67:
663 em_device.fec = FEC_6_7;
664 break;
665 case 78:
666 em_device.fec = FEC_7_8;
667 break;
668 case 89:
669 em_device.fec = FEC_8_9;
670 break;
671 case 35:
672 em_device.fec = FEC_3_5;
673 break;
674 case 910:
675 em_device.fec = FEC_9_10;
676 break;
677 default:
678 em_device.fec = FEC_AUTO;
679 break;
680 }
681 switch (args[5]) {
682 case 2:
683 em_device.transmission = TRANSMISSION_MODE_2K;
684 break;
685 case 8:
686 em_device.transmission = TRANSMISSION_MODE_8K;
687 break;
688 case 4:
689 em_device.transmission = TRANSMISSION_MODE_4K;
690 break;
691 case 1:
692 em_device.transmission = TRANSMISSION_MODE_1K;
693 break;
694 case 16:
695 em_device.transmission = TRANSMISSION_MODE_16K;
696 break;
697 case 32:
698 em_device.transmission = TRANSMISSION_MODE_32K;
699 break;
700 default:
701 em_device.transmission = TRANSMISSION_MODE_AUTO;
702 break;
703 }
704 switch (args[6]) {
705 case 32:
706 em_device.guard = GUARD_INTERVAL_1_32;
707 break;
708 case 16:
709 em_device.guard = GUARD_INTERVAL_1_16;
710 break;
711 case 8:
712 em_device.guard = GUARD_INTERVAL_1_8;
713 break;
714 case 4:
715 em_device.guard = GUARD_INTERVAL_1_4;
716 break;
717 case 128:
718 em_device.guard = GUARD_INTERVAL_1_128;
719 break;
720 case 19128:
721 em_device.guard = GUARD_INTERVAL_19_128;
722 break;
723 case 19256:
724 em_device.guard = GUARD_INTERVAL_19_256;
725 break;
726 default:
727 em_device.guard = GUARD_INTERVAL_AUTO;
728 break;
729 }
730 switch (args[7]) {
731 case 0:
732 em_device.hierarchy = HIERARCHY_NONE;
733 break;
734 case 1:
735 em_device.hierarchy = HIERARCHY_1;
736 break;
737 case 2:
738 em_device.hierarchy = HIERARCHY_2;
739 break;
740 case 4:
741 em_device.hierarchy = HIERARCHY_4;
742 break;
743 default:
744 em_device.hierarchy = HIERARCHY_AUTO;
745 break;
746 }
747 if (em_device.delsys == SYS_DVBT2)
748 sprintf(mbuf, "P%d", em_device.stream_id);
749 else
750 mbuf[0] = 0;
751 //EM_INFO("%s: '%-55s' -> %-8s f = %6d kHz I%sB%sC%sD%sT%sG%sY%s%s\n", \
752 // __FUNCTION__, str, \
753 // xine_modulation_name(em_device.modulation), \
754 // freq_scale(em_device.frequency, 1e-3), \
755 // vdr_inversion_name(em_device.inversion), \
756 // vdr_bandwidth_name(em_device.bandwidth_hz), \
757 // vdr_fec_name(em_device.fec), \
758 // vdr_fec_name(FEC_NONE), \
759 // vdr_transmission_mode_name(em_device.transmission), \
760 // vdr_guard_name(em_device.guard), \
761 // vdr_hierarchy_name(em_device.hierarchy), \
762 // mbuf);
763 break;
764 case SCAN_TERRCABLE_ATSC:
765 sscanf(str, "%8s f=%u kHz ", mbuf, &args[0]);
766 if (strncmp(mbuf, "QAM64", 5) == 0)
767 em_device.modulation = QAM_64;
768 else if (strncmp(mbuf, "QAM256", 6) == 0)
769 em_device.modulation = QAM_256;
770 else if (strncmp(mbuf, "8VSB", 4) == 0)
771 em_device.modulation = VSB_8;
772 else if (strncmp(mbuf, "16VSB", 5) == 0)
773 em_device.modulation = VSB_16;
774 else
775 em_device.modulation = QAM_AUTO;
776 em_device.frequency = 1000 * args[0];
777 //EM_INFO("%s: '%-55s' -> %-8s f=%d kHz\n", \
778 // __FUNCTION__, str, \
779 // atsc_mod_to_txt(em_device.modulation), \
780 // freq_scale(em_device.frequency, 1e-3));
781 break;
782 case SCAN_CABLE:
783 sscanf(str, "%8s f = %u kHz S%uC%u ", mbuf, &args[0], &args[1],
784 &args[2]);
785 if (strncmp(mbuf, "QAM_16", 6) == 0)
786 em_device.modulation = QAM_16;
787 else if (strncmp(mbuf, "QAM_32", 6) == 0)
788 em_device.modulation = QAM_32;
789 else if (strncmp(mbuf, "QAM_64", 6) == 0)
790 em_device.modulation = QAM_64;
791 else if (strncmp(mbuf, "QAM_128", 7) == 0)
792 em_device.modulation = QAM_128;
793 else if (strncmp(mbuf, "QAM_256", 7) == 0)
794 em_device.modulation = QAM_256;
795 else
796 em_device.modulation = QAM_AUTO;
797 em_device.frequency = 1000 * args[0];
798 em_device.symbolrate = 1000 * args[1];
799 em_device.fec = FEC_NONE;
800 //EM_INFO("%s: '%-55s' -> %-8s f = %d kHz S%dC%s\n", \
801 // __FUNCTION__, str, \
802 // xine_modulation_name(em_device.modulation), \
803 // freq_scale(em_device.frequency, 1e-3), \
804 // freq_scale(em_device.symbol_rate, 1e-3), \
805 // vdr_fec_name(FEC_NONE));
806 break;
807 case SCAN_SATELLITE:
808 em_device.delsys = SYS_DVBS;
809 em_device.rolloff = ROLLOFF_AUTO;
810 em_device.pilot = PILOT_AUTO;
811 if (strlen(str) > 2)
812 if (str[1] == '2')
813 em_device.delsys = SYS_DVBS2;
814 p = strchr(str, 'f');
815 if (!p || !*p)
816 return 0;
817 sscanf(p, "f = %u kHz %c SR = %5d %4s 0,%s %5s ", &args[0], &c,
818 &args[1], fecbuf, robuf, mbuf);
819 em_device.frequency = 1000 * args[0];
820 if (c == 'V')
821 em_device.polarization = POLARIZATION_VERTICAL;
822 else if (c == 'R')
823 em_device.polarization = POLARIZATION_CIRCULAR_RIGHT;
824 else if (c == 'L')
825 em_device.polarization = POLARIZATION_CIRCULAR_LEFT;
826 else
827 em_device.polarization = POLARIZATION_HORIZONTAL;
828 em_device.symbolrate = 1000 * args[1];
829 if (strncmp(fecbuf, "NONE", 4) == 0)
830 em_device.fec = FEC_NONE;
831 else if (strncmp(fecbuf, "1/2", 3) == 0)
832 em_device.fec = FEC_1_2;
833 else if (strncmp(fecbuf, "2/3", 3) == 0)
834 em_device.fec = FEC_2_3;
835 else if (strncmp(fecbuf, "3/4", 3) == 0)
836 em_device.fec = FEC_3_4;
837 else if (strncmp(fecbuf, "4/5", 3) == 0)
838 em_device.fec = FEC_4_5;
839 else if (strncmp(fecbuf, "5/6", 3) == 0)
840 em_device.fec = FEC_5_6;
841 else if (strncmp(fecbuf, "6/7", 3) == 0)
842 em_device.fec = FEC_6_7;
843 else if (strncmp(fecbuf, "7/8", 3) == 0)
844 em_device.fec = FEC_7_8;
845 else if (strncmp(fecbuf, "8/9", 3) == 0)
846 em_device.fec = FEC_8_9;
847 else if (strncmp(fecbuf, "3/5", 3) == 0)
848 em_device.fec = FEC_3_5;
849 else if (strncmp(fecbuf, "9/10", 4) == 0)
850 em_device.fec = FEC_9_10;
851 else if (strncmp(fecbuf, "AUTO", 4) == 0)
852 em_device.fec = FEC_AUTO;
853 else
854 em_device.fec = FEC_AUTO;
855 if (strncmp(robuf, "35", 2) == 0)
856 em_device.rolloff = ROLLOFF_35;
857 else if (strncmp(robuf, "25", 2) == 0)
858 em_device.rolloff = ROLLOFF_25;
859 else if (strncmp(robuf, "20", 2) == 0)
860 em_device.rolloff = ROLLOFF_20;
861 else if (strncmp(robuf, "AUTO", 4) == 0)
862 em_device.rolloff = ROLLOFF_35;
863 else
864 em_device.rolloff = ROLLOFF_35;
865 if (strncmp(mbuf, "QPSK", 4) == 0)
866 em_device.modulation = QPSK;
867 else if (strncmp(mbuf, "8PSK", 4) == 0)
868 em_device.modulation = PSK_8;
869 else if (strncmp(mbuf, "16APSK", 6) == 0)
870 em_device.modulation = APSK_16;
871 else if (strncmp(mbuf, "32APSK", 6) == 0)
872 em_device.modulation = APSK_32;
873 else
874 em_device.modulation = QPSK;
875 EM_INFO
876 ("%s: '%-55s' -> %-2s f = %d kHz %s SR = %5d %4s 0,%s %5s\n",
877 __FUNCTION__, str,
878 sat_delivery_system_to_txt(em_device.delsys),
879 freq_scale(em_device.frequency, 1e-3),
880 sat_pol_to_txt(em_device.polarization),
881 freq_scale(em_device.symbolrate, 1e-3),
882 sat_fec_to_txt(em_device.fec),
883 sat_rolloff_to_txt(em_device.rolloff),
884 sat_mod_to_txt(em_device.modulation));
885 break;
886 default:
887 fatal("could not find scan type for '%s'\n", str);
888 }
889 return 1; //success.
890 }
891
parse_intro(uint16_t table_id,const char * str,uint16_t * i1,uint16_t * i2)892 static void parse_intro(uint16_t table_id, const char *str, uint16_t * i1,
893 uint16_t * i2)
894 {
895 unsigned tmp;
896 switch (table_id) {
897 case TABLE_PAT:
898 sscanf(str, "PAT (xxxx:xxxx:%hu)", i1);
899 break;
900 case TABLE_NIT_ACT:
901 sscanf(str, "NIT(act): (xxxx:%hu:xxxx)", i1);
902 break;
903 case TABLE_NIT_OTH:
904 sscanf(str, "NIT(oth): (xxxx:%hu:xxxx)", i1);
905 break;
906 case TABLE_SDT_ACT:
907 sscanf(str, "SDT(actual TS, transport_stream_id %hu ", i1);
908 break;
909 case TABLE_SDT_OTH:
910 sscanf(str, "SDT(other TS, transport_stream_id %hu ", i1);
911 break;
912 case TABLE_PMT:
913 sscanf(str, "PMT %hu (0x%04x) for service %hu ", i1, &tmp, i2);
914 break;
915 default:;
916 }
917 //EM_INFO("table_id = %x -> %d %d\n", table_id, *i1, i2?*i2:-1);
918 }
919
parse_logfile(const char * log)920 static int parse_logfile(const char *log)
921 {
922 FILE *logfile = NULL;
923 char *line = (char *)calloc(1, 256);
924 char *p;
925 int pid = 0, table_id = -1, len = 0, line_no = 0;
926 uint16_t original_network_id = 0, network_id = 0, transport_stream_id =
927 0;
928 uint16_t service_id = 0, pmt_pid = 0;
929 int dev_props = 0;
930 sidata_t *sidata = NULL;
931 bool delsys_list = false;
932 em_device.scantype = SCAN_UNDEFINED;
933 em_device.w_scan_version = em_device.w_scan_flags = 0; // logging w_scan's version.
934
935 if (!log || !*log) {
936 free(line);
937 error("could not open logfile: invalid file name.\n");
938 return 0; // err
939 }
940
941 logfile = fopen(log, "r");
942 if (!logfile) {
943 free(line);
944 fatal("cannot open '%s': error %d %s\n", log, errno,
945 strerror(errno));
946 return 0; // err
947 }
948
949 while (fgets(line, 256, logfile) != NULL) {
950 bool is_tp = false;
951 line_no++;
952
953 // --- get logging w_scan's version -------------------------------------------------------------------------------
954 if (!em_device.w_scan_version) {
955 sscanf(line,
956 "w_scan version %u (compiled for DVB API 5.xx)",
957 &em_device.w_scan_version);
958 EM_INFO("detected w_scan version %u\n",
959 em_device.w_scan_version);
960 if (em_device.w_scan_version
961 && (em_device.w_scan_version < 20140614)) {
962 EM_INFO("using flag EM_OLD_DELSYSLIST\n");
963 em_device.w_scan_flags |= EM_OLD_DELSYSLIST;
964 }
965 if (em_device.w_scan_version
966 && (em_device.w_scan_version < 20140529)) {
967 EM_INFO("using flag EM_OLD_SI_HEADER\n");
968 em_device.w_scan_flags |= EM_OLD_SI_HEADER;
969 }
970 if (em_device.w_scan_version
971 && (em_device.w_scan_version < 20140423)) {
972 EM_INFO("using flag EM_OLD_APIDISP\n");
973 em_device.w_scan_flags |= EM_OLD_APIDISP;
974 EM_INFO("using flag EM_OLD_APIDISP\n");
975 em_device.w_scan_flags |= EM_HEXDUMP_BUG;
976 }
977 continue;
978 }
979 // --- end logging w_scan's version -------------------------------------------------------------------------------
980
981 // --- get scan type ----------------------------------------------------------------------------------------------
982 if (em_device.scantype == SCAN_UNDEFINED) {
983 if (strstr(line, "scan type")) {
984 if (strstr(line, "CABLE"))
985 em_device.scantype = SCAN_CABLE;
986 else if (strstr(line, "SATELLITE"))
987 em_device.scantype = SCAN_SATELLITE;
988 else if (strstr(line, "TERRCABLE_ATSC"))
989 em_device.scantype =
990 SCAN_TERRCABLE_ATSC;
991 else if (strstr(line, "TERRESTRIAL"))
992 em_device.scantype = SCAN_TERRESTRIAL;
993 else
994 fatal
995 ("cannot read scan type from '%s'\n",
996 line);
997 }
998 continue; // anything else is meaningless until this is known.
999 }
1000 // --- end scan type ----------------------------------------------------------------------------------------------
1001
1002 // --- get the properties of dvb device ---------------------------------------------------------------------------
1003 if (dev_props < 2) {
1004 float fmin, fmax;
1005 if (strstr
1006 (line,
1007 "-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_"))
1008 {
1009 dev_props = 2;
1010 continue;
1011 }
1012 if (strstr
1013 (line,
1014 "-_-_-_-_ Getting frontend capabilities-_-_-_-_"))
1015 {
1016 dev_props = 1;
1017 continue;
1018 }
1019 if (dev_props != 1)
1020 continue;
1021
1022 // used DVB API
1023 if (strstr(line, "Using DVB API ")) {
1024 if (em_device.w_scan_flags & EM_OLD_APIDISP) {
1025 sscanf(line, "Using DVB API %x.%x",
1026 &em_api.major, &em_api.minor);
1027 } else {
1028 sscanf(line, "Using DVB API %u.%u",
1029 &em_api.major, &em_api.minor);
1030 }
1031 continue;
1032 }
1033 // capabilities: frontend name
1034 if ((p = strstr(line, "frontend "))
1035 && strstr(line, " supports")) {
1036 char *pEnd;
1037 p += 10;
1038 pEnd = strchr(p, 39);
1039 *pEnd = 0;
1040 strncpy(&em_device.fe_info.name[0], p, 128);
1041 em_device.T2_delsys_bug =
1042 strstr(em_device.fe_info.name,
1043 "CXD2820R") != NULL;
1044 continue;
1045 }
1046 // all other capabilities.
1047 if (em_device.scantype == SCAN_TERRESTRIAL) {
1048 if (strstr(line, "DVB-T2"))
1049 em_device.fe_info.caps |=
1050 FE_CAN_2G_MODULATION;
1051 if (strstr(line, "INVERSION_AUTO")
1052 && (strstr(line, "not supported") == NULL))
1053 em_device.fe_info.caps |=
1054 FE_CAN_INVERSION_AUTO;
1055 if (strstr(line, "QAM_AUTO")
1056 && (strstr(line, "not supported") == NULL))
1057 em_device.fe_info.caps |=
1058 FE_CAN_QAM_AUTO;
1059 if (strstr(line, "TRANSMISSION_MODE_AUTO")
1060 && (strstr(line, "not supported") == NULL))
1061 em_device.fe_info.caps |=
1062 FE_CAN_TRANSMISSION_MODE_AUTO;
1063 if (strstr(line, "GUARD_INTERVAL_AUTO")
1064 && (strstr(line, "not supported") == NULL))
1065 em_device.fe_info.caps |=
1066 FE_CAN_GUARD_INTERVAL_AUTO;
1067 if (strstr(line, "HIERARCHY_AUTO")
1068 && (strstr(line, "not supported") == NULL))
1069 em_device.fe_info.caps |=
1070 FE_CAN_HIERARCHY_AUTO;
1071 if (strstr(line, "FEC_AUTO")
1072 && (strstr(line, "not supported") == NULL))
1073 em_device.fe_info.caps |=
1074 FE_CAN_FEC_AUTO;
1075 if (sscanf
1076 (line, "FREQ (%fMHz ... %fMHz)", &fmin,
1077 &fmax) == 2) {
1078 em_device.fe_info.frequency_min =
1079 (0.5 + fmin * MHz);
1080 em_device.fe_info.frequency_max =
1081 (0.5 + fmax * MHz);
1082 }
1083 continue;
1084 } else if (em_device.scantype == SCAN_CABLE) {
1085 if (strstr(line, "DVB-C2"))
1086 em_device.fe_info.caps |=
1087 FE_CAN_2G_MODULATION;
1088 if (strstr(line, "INVERSION_AUTO")
1089 && (strstr(line, "not supported") == NULL))
1090 em_device.fe_info.caps |=
1091 FE_CAN_INVERSION_AUTO;
1092 if (strstr(line, "QAM_AUTO")
1093 && (strstr(line, "not supported") == NULL))
1094 em_device.fe_info.caps |=
1095 FE_CAN_QAM_AUTO;
1096 if (strstr(line, "FEC_AUTO")
1097 && (strstr(line, "not supported") == NULL))
1098 em_device.fe_info.caps |=
1099 FE_CAN_FEC_AUTO;
1100 if (sscanf
1101 (line, "FREQ (%fMHz ... %fMHz)", &fmin,
1102 &fmax) == 2) {
1103 em_device.fe_info.frequency_min =
1104 (0.5 + fmin * MHz);
1105 em_device.fe_info.frequency_max =
1106 (0.5 + fmax * MHz);
1107 }
1108 if (sscanf
1109 (line, "SRATE (%fMSym/s ... %fMSym/s)",
1110 &fmin, &fmax) == 2) {
1111 em_device.fe_info.symbol_rate_min =
1112 (0.5 + fmin * MHz);
1113 em_device.fe_info.symbol_rate_max =
1114 (0.5 + fmax * MHz);
1115 }
1116 continue;
1117 } else if (em_device.scantype == SCAN_TERRCABLE_ATSC) {
1118 if (strstr(line, "INVERSION_AUTO")
1119 && (strstr(line, "not supported") == NULL))
1120 em_device.fe_info.caps |=
1121 FE_CAN_INVERSION_AUTO;
1122 if (strstr(line, "8VSB"))
1123 em_device.fe_info.caps |= FE_CAN_8VSB;
1124 if (strstr(line, "16VSB"))
1125 em_device.fe_info.caps |= FE_CAN_16VSB;
1126 if (strstr(line, "QAM_64"))
1127 em_device.fe_info.caps |= FE_CAN_QAM_64;
1128 if (strstr(line, "QAM_256"))
1129 em_device.fe_info.caps |=
1130 FE_CAN_QAM_256;
1131 if (sscanf
1132 (line, "FREQ (%fMHz ... %fMHz)", &fmin,
1133 &fmax) == 2) {
1134 em_device.fe_info.frequency_min =
1135 (0.5 + fmin * MHz);
1136 em_device.fe_info.frequency_max =
1137 (0.5 + fmax * MHz);
1138 }
1139 continue;
1140 } else if (em_device.scantype == SCAN_SATELLITE) {
1141 if (strstr(line, "QAM_AUTO")
1142 && (strstr(line, "not supported") == NULL))
1143 em_device.fe_info.caps |=
1144 FE_CAN_QAM_AUTO;
1145 if (strstr(line, "DVB-S2")
1146 && (strstr(line, "not supported") == NULL))
1147 em_device.fe_info.caps |=
1148 FE_CAN_2G_MODULATION;
1149 if (strstr(line, "DVB-S")
1150 && (strstr(line, "not supported") == NULL))
1151 em_device.fe_info.caps |= FE_CAN_QPSK;
1152 if (sscanf
1153 (line, "FREQ (%fGHz ... %fGHz)", &fmin,
1154 &fmax) == 2) {
1155 em_device.fe_info.frequency_min =
1156 (0.5 + fmin * MHz);
1157 em_device.fe_info.frequency_max =
1158 (0.5 + fmax * MHz);
1159 }
1160 if (sscanf
1161 (line, "SRATE (%fMSym/s ... %fMSym/s)",
1162 &fmin, &fmax) == 2) {
1163 em_device.fe_info.symbol_rate_min =
1164 (0.5 + fmin * MHz);
1165 em_device.fe_info.symbol_rate_max =
1166 (0.5 + fmax * MHz);
1167 }
1168 continue;
1169 } else
1170 fatal
1171 ("unsupported frontend type, cannot parse '%s'\n",
1172 line);
1173 }
1174
1175 if (em_device.w_scan_flags & EM_OLD_DELSYSLIST) {
1176 EM_INFO("%d: lookup oldstyle delsys hex array\n",
1177 line_no);
1178 if (strstr(line, "=====================") == NULL) {
1179 info("skip line %d: '%s'\n", line_no, line);
1180 } else {
1181 int len = 0;
1182 unsigned tmp, args[16];
1183 //EM_INFO("lookup oldstyle delsys hex array: started\n");
1184
1185 while (fgets(line, 256, logfile) != NULL) {
1186 EM_INFO("checking line '%s'", line);
1187 line_no++;
1188 if (strstr
1189 (line,
1190 " ======================"))
1191 continue;
1192 if (!len) {
1193 sscanf(line, " len = %d",
1194 &len);
1195 continue;
1196 }
1197 if (len) {
1198 int i;
1199 int nitems = sscanf(line,
1200 " 0x%X: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X :",
1201 &tmp,
1202 &args[0],
1203 &args[1],
1204 &args[2],
1205 &args[3],
1206 &args[4],
1207 &args[5],
1208 &args[6],
1209 &args[7],
1210 &args[8],
1211 &args[9],
1212 &args[10],
1213 &args[11],
1214 &args[12],
1215 &args[13],
1216 &args[14],
1217 &args[15]);
1218 EM_INFO("nitems = %d\n",
1219 nitems);
1220 if (!nitems)
1221 continue;
1222 for (i = 0; i < len; i++)
1223 em_device.delsystems
1224 [em_device.ndelsystems++]
1225 =
1226 (fe_delivery_system_t)
1227 args[i];
1228 //for(i=0; i<em_device.ndelsystems; i++)
1229 // info("delsys %d\n", em_device.delsystems[i]);
1230 break;
1231 }
1232 }
1233 em_device.w_scan_flags &= ~EM_OLD_DELSYSLIST;
1234 }
1235 continue;
1236 }
1237 if ((p = strstr(line, " check ")) != NULL) {
1238 delsys_list = true;
1239 continue;
1240 }
1241 if (delsys_list) {
1242 const char *dname[] = {
1243 "UNDEFINED", "DVB-C ann.A", "DVB-C ann.B",
1244 "DVB-T", "DSS", "DVB-S", "DVB-S2", "DVB-H",
1245 "ISDB-T", "ISDB-S",
1246 "ISDB-C", "ATSC", "ATSC/MH", "DTMB", "CMMB",
1247 "DAB", "DVB-T2", "TURBO-FEC", "DVB-C ann.C"
1248 };
1249 uint8_t i = 0;
1250 bool delsys = false;
1251 p = strchr(line, '\n');
1252 if (p)
1253 *p = 0;
1254 p = line;
1255 while (p && isspace(*p))
1256 p++;
1257
1258 for (i = 0; i < sizeof(dname) / sizeof(dname[0]); i++) {
1259 //EM_INFO("'%s' = '%s'?\n",p,dname[i]);
1260 if (strncmp(p, dname[i], strlen(p)) == 0) {
1261 em_device.delsystems[em_device.
1262 ndelsystems++]
1263 = (fe_delivery_system_t) i;
1264 delsys = true;
1265 break;
1266 }
1267 }
1268 if (delsys)
1269 continue;
1270 else
1271 delsys_list = false;
1272 }
1273
1274 if (dev_props != 2)
1275 continue; // continue only after frontend reading.
1276 // --- end of dvb device ------------------------------------------------------------------------------------------
1277
1278 // --- we tuned to a new transponder. all si data belongs to this new tp ------------------------------------------
1279 if (strncmp(line, " signal ok: ", 19) == 0)
1280 is_tp = true; // ' signal ok: <FOOBAR>'
1281 if (strncmp(line, "tune to: ", 9) == 0)
1282 is_tp = true; // 'tune to: <FOOBAR>'
1283 if (strncmp(line, "signal ok:", 10) == 0) {
1284 if (fgets(line, 256, logfile) != NULL) {
1285 *line = ':';
1286 }
1287 line_no++;
1288 is_tp = true;
1289 }
1290 if (is_tp) {
1291 char *p = strchr(line, ':');
1292 p++;
1293 while (isspace(*p))
1294 p++;
1295 parse_tp(p);
1296 table_id = -1;
1297 continue;
1298 }
1299 // --- end of tp reading ------------------------------------------------------------------------------------------
1300
1301 // --- we got data from demux. first: intro with table_id_ext -----------------------------------------------------
1302 if (strstr(line, "no data from"))
1303 continue;
1304 if ((p = strstr(line, "PAT (xxxx:xxxx:")) != NULL) {
1305 table_id = TABLE_PAT;
1306 parse_intro(table_id, p, &transport_stream_id, 0);
1307 pid = PID_PAT;
1308 continue;
1309 }
1310 if ((p = strstr(line, "NIT(act): (xxxx:")) != NULL) {
1311 table_id = TABLE_NIT_ACT;
1312 parse_intro(table_id, p, &network_id, 0);
1313 pid = PID_NIT_ST;
1314 continue;
1315 }
1316 if ((p = strstr(line, "NIT(oth): (xxxx:")) != NULL) {
1317 table_id = TABLE_NIT_OTH;
1318 parse_intro(table_id, p, &network_id, 0);
1319 pid = PID_NIT_ST;
1320 continue;
1321 }
1322 if ((p = strstr(line, "SDT(act")) != NULL) {
1323 table_id = TABLE_SDT_ACT;
1324 parse_intro(table_id, p, &transport_stream_id, 0);
1325 pid = PID_SDT_BAT_ST;
1326 continue;
1327 }
1328 if ((p = strstr(line, "SDT(oth")) != NULL) {
1329 table_id = TABLE_SDT_OTH;
1330 parse_intro(table_id, p, &transport_stream_id, 0);
1331 pid = PID_SDT_BAT_ST;
1332 continue;
1333 }
1334 if ((p = strstr(line, "PMT ")) != NULL) {
1335 table_id = TABLE_PMT;
1336 parse_intro(table_id, p, &pmt_pid, &service_id);
1337 pid = pmt_pid;
1338 continue;
1339 }
1340
1341 if ((em_device.w_scan_flags & EM_OLD_SI_HEADER)
1342 && !strncmp(line, "parse_section", 13)) {
1343 unsigned args[9];
1344 int nargs, tmp;
1345 // parse_section:1376: pid 0x10 tid 0x40 table_id_ext 0x0056, 2/3 (version 16)
1346 // parse_section:1376: pid 17 (0x11), tid 66 (0x42), table_id_ext 30 (0x001e), section_number 0, last_section_number 0, version 3\n"
1347 nargs = sscanf(line, "parse_section:%d: pid %x tid %x table_id_ext %x, %i/%i (version %i)", //",
1348 &tmp, &args[0], &args[1], &args[2], &args[3], &args[4], &args[5]); //);
1349 if (nargs != 7)
1350 nargs =
1351 sscanf(line,
1352 "parse_section:%d: pid %d (%x), tid %d (%x), table_id_ext %d (%x), section_number %i, last_section_number %i, version %i\n",
1353 &tmp, &args[0], &args[1], &args[2],
1354 &args[3], &args[4], &args[5],
1355 &args[6], &args[7], &args[8]);
1356 //if (nargs) info("found %d args---------\n", nargs);
1357 if ((nargs == 7) || (nargs == 10)) {
1358 EM_INFO("found table. nargs = %d\n", nargs);
1359 table_id =
1360 (nargs == 7) ? (int)args[1] : (nargs ==
1361 10) ? (int)
1362 args[2] : table_id;
1363 switch (table_id) {
1364 case TABLE_PAT:
1365 transport_stream_id =
1366 (nargs ==
1367 7) ? (int)args[2] : (nargs ==
1368 10) ? (int)
1369 args[4] : transport_stream_id;
1370 break;
1371 case TABLE_NIT_ACT:
1372 case TABLE_NIT_OTH:
1373 network_id =
1374 (nargs ==
1375 7) ? (int)args[2] : (nargs ==
1376 10) ? (int)
1377 args[4] : network_id;
1378 break;
1379 case TABLE_SDT_ACT:
1380 case TABLE_SDT_OTH:
1381 transport_stream_id =
1382 (nargs ==
1383 7) ? (int)args[2] : (nargs ==
1384 10) ? (int)
1385 args[4] : transport_stream_id;
1386 break;
1387 case TABLE_PMT:
1388 pmt_pid = ((nargs == 7)
1389 || (nargs ==
1390 10)) ? (int)args[0] :
1391 pmt_pid;
1392 service_id =
1393 (nargs ==
1394 7) ? (int)args[2] : (nargs ==
1395 10) ? (int)
1396 args[4] : service_id;
1397 break;
1398 default:
1399 info("invalid table id %d\n", table_id);
1400 }
1401 if (fgets(line, 256, logfile) != NULL) {
1402 EM_INFO("next: %s\n", line);
1403 }
1404 line_no++; //"NIT (act"
1405 if (fgets(line, 256, logfile) != NULL) {
1406 EM_INFO("next: %s\n", line);
1407 }
1408 line_no++; //" ===================== parse_"
1409 if (fgets(line, 256, logfile) != NULL) {
1410 EM_INFO("next: %s\n", line);
1411 }
1412 line_no++; //" len = "
1413 }
1414 }
1415
1416 if (strstr
1417 (line,
1418 "========================================================================"))
1419 {
1420 table_id = -1;
1421 continue;
1422 }
1423 if (table_id < 0)
1424 continue; // we found something, which we cannot assign to any table.
1425
1426 if (strstr(line, " len = ")) {
1427 sscanf(line, " len = %d", &len);
1428 if (len > 0) {
1429 sidata =
1430 (sidata_t *) calloc(1, sizeof(sidata_t));
1431 sidata->t.frequency = em_device.frequency;
1432 sidata->t.inversion = em_device.inversion;
1433 switch (em_device.delsys) {
1434 case SYS_DVBT:
1435 case SYS_DVBT2:
1436 sidata->t.type = SCAN_TERRESTRIAL;
1437 sidata->t.bandwidth =
1438 em_device.bandwidth_hz;
1439 sidata->t.coderate = em_device.fec;
1440 sidata->t.coderate_LP = FEC_AUTO;
1441 sidata->t.modulation =
1442 em_device.modulation;
1443 sidata->t.transmission =
1444 em_device.transmission;
1445 sidata->t.guard = em_device.guard;
1446 sidata->t.hierarchy =
1447 em_device.hierarchy;
1448 sidata->t.delsys = em_device.delsys;
1449 break;
1450 case SYS_DVBC_ANNEX_A:
1451 case SYS_DVBC_ANNEX_C:
1452 sidata->t.type = SCAN_CABLE;
1453 sidata->t.delsys = em_device.delsys;
1454 sidata->t.modulation =
1455 em_device.modulation;
1456 sidata->t.symbolrate =
1457 em_device.symbolrate;
1458 break;
1459 case SYS_DVBS:
1460 case SYS_DVBS2:
1461 sidata->t.type = SCAN_SATELLITE;
1462 sidata->t.rolloff = em_device.rolloff;
1463 sidata->t.pilot = em_device.pilot;
1464 sidata->t.delsys = em_device.delsys;
1465 sidata->t.polarization =
1466 em_device.polarization;
1467 sidata->t.coderate = em_device.fec;
1468 sidata->t.symbolrate =
1469 em_device.symbolrate;
1470 sidata->t.modulation =
1471 em_device.modulation;
1472 break;
1473 case SYS_ATSC:
1474 sidata->t.type = SCAN_TERRCABLE_ATSC;
1475 default:
1476 fatal("unsupported del sys.\n");
1477 }
1478 sidata->pid = pid;
1479 sidata->table_id = table_id;
1480 sidata->original_network_id =
1481 original_network_id;
1482 sidata->network_id = network_id;
1483 sidata->transport_stream_id =
1484 transport_stream_id;
1485 sidata->service_id = service_id;
1486 switch (table_id) {
1487 case TABLE_PAT:
1488 sidata->table_id_ext =
1489 transport_stream_id;
1490 break;
1491 case TABLE_PMT:
1492 sidata->table_id_ext = service_id;
1493 sidata->pid = pmt_pid;
1494 break;
1495 case TABLE_NIT_ACT:
1496 case TABLE_NIT_OTH:
1497 sidata->table_id_ext = network_id;
1498 break;
1499 case TABLE_SDT_ACT:
1500 case TABLE_SDT_OTH:
1501 sidata->table_id_ext =
1502 transport_stream_id;
1503 break;
1504 default:
1505 info("%s: no table id.\n",
1506 __FUNCTION__);
1507 }
1508 //EM_INFO("line %-5d: new sidata: table_id = %-8s, table_id_ext = %u, pid = %u (%u:%u:%u)\n", \
1509 // line_no, \
1510 // sidata->table_id == TABLE_PAT ?"PAT": \
1511 // sidata->table_id == TABLE_NIT_ACT?"NIT(act)": \
1512 // sidata->table_id == TABLE_NIT_OTH?"NIT(oth)": \
1513 // sidata->table_id == TABLE_SDT_ACT?"SDT(act)": \
1514 // sidata->table_id == TABLE_SDT_OTH?"SDT(oth)": \
1515 // sidata->table_id == TABLE_PMT ?"PMT":"---ERROR---" , \
1516 // sidata->table_id_ext, sidata->pid, \
1517 // sidata->original_network_id, sidata->network_id, sidata->transport_stream_id);
1518 }
1519 continue;
1520 }
1521 if (strstr(line, "=== parse"))
1522 continue;
1523
1524 if (!sidata)
1525 fatal("%d: sidata invalid for table_id 0x%02x\n",
1526 line_no, table_id);
1527 if (strlen(line) > 8) {
1528 if ((p = strstr(line, " 0x")) != NULL) {
1529 unsigned tmp, args[16];
1530 int nitems = 0, i;
1531 if (len > 0) {
1532 p = strchr(line, '\n');
1533 if (p)
1534 *p = 0;
1535
1536 nitems =
1537 sscanf(line,
1538 " 0x%X: %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X :",
1539 &tmp, &args[0], &args[1],
1540 &args[2], &args[3], &args[4],
1541 &args[5], &args[6], &args[7],
1542 &args[8], &args[9],
1543 &args[10], &args[11],
1544 &args[12], &args[13],
1545 &args[14], &args[15]);
1546 len -= (nitems - 1);
1547 //EM_INFO("%d: '%-80s' (%d bytes left)\n", line_no, line, len);
1548
1549 for (i = 0; i < nitems - 1; i++)
1550 sidata->buf[sidata->len++] =
1551 args[i];
1552 if (len < 1) {
1553 //info("line %d\n", line_no);
1554 //switch(table_id) {
1555 // case TABLE_PAT:
1556 // info("PAT (xxxx:xxxx:%u)\n", transport_stream_id);
1557 // break;
1558 // case TABLE_NIT_ACT:
1559 // case TABLE_NIT_OTH:
1560 // info("%s: (xxxx:%u:xxxx)\n", table_id == 0x40?"NIT(act)":"NIT(oth)", network_id);
1561 // break;
1562 // case TABLE_SDT_ACT:
1563 // case TABLE_SDT_OTH:
1564 // info("SDT(%s TS, transport_stream_id %d (0x%04x) )\n", table_id == 0x42 ? "actual":"other",
1565 // transport_stream_id, transport_stream_id);
1566 // break;
1567 // case TABLE_PMT:
1568 // info("PMT %d (0x%04x) for service %d (0x%04x)\n", pid, pid, service_id, service_id);
1569 // break;
1570 // default:
1571 // info("??? unknown table_id %d\n", table_id);
1572 // }
1573 if (em_device.
1574 w_scan_flags &
1575 EM_HEXDUMP_BUG) {
1576 // each sections hexdump misses two bytes, because of bug in older versions. :(
1577 // those are really lost in logfile && not recoverable.
1578 sidata->buf[sidata->
1579 len++] = 0;
1580 sidata->buf[sidata->
1581 len++] = 0;
1582 }
1583 //hexdump("sidata", &sidata->buf[0], sidata->len);
1584 AddItem(em_sidata, sidata);
1585 sidata = NULL;
1586 }
1587
1588 }
1589 }
1590 }
1591 }
1592 fclose(logfile);
1593 free(line);
1594 return 1;
1595 }
1596