1 /*
2 * Copyright (c) 2011-2012 - Mauro Carvalho Chehab
3 * Copyright (c) 2013 - Andre Roth <neolynx@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation version 2.1 of the License.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18 */
19
20 /******************************************************************************
21 * Parse DVB tables
22 * According with:
23 * ETSI EN 301 192 V1.5.1 (2009-11)
24 * ISO/IEC 13818-1:2007
25 * ETSI EN 300 468 V1.11.1 (2010-04)
26 *****************************************************************************/
27
28 #include <errno.h>
29 #include <fcntl.h>
30 #include <stdint.h>
31 #include <stdio.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <sys/ioctl.h>
35 #include <sys/stat.h>
36 #include <sys/types.h>
37 #include <stdlib.h>
38 #include <sys/time.h>
39
40 #include "dvb-fe-priv.h"
41 #include <libdvbv5/dvb-scan.h>
42 #include <libdvbv5/dvb-frontend.h>
43 #include <libdvbv5/descriptors.h>
44 #include <libdvbv5/crc32.h>
45 #include <libdvbv5/dvb-file.h>
46 #include <libdvbv5/dvb-scan.h>
47 #include <libdvbv5/dvb-log.h>
48 #include <libdvbv5/dvb-demux.h>
49 #include <libdvbv5/descriptors.h>
50 #include <libdvbv5/header.h>
51 #include <libdvbv5/pat.h>
52 #include <libdvbv5/pmt.h>
53 #include <libdvbv5/nit.h>
54 #include <libdvbv5/sdt.h>
55 #include <libdvbv5/vct.h>
56 #include <libdvbv5/desc_extension.h>
57 #include <libdvbv5/desc_cable_delivery.h>
58 #include <libdvbv5/desc_isdbt_delivery.h>
59 #include <libdvbv5/desc_partial_reception.h>
60 #include <libdvbv5/desc_terrestrial_delivery.h>
61 #include <libdvbv5/desc_t2_delivery.h>
62 #include <libdvbv5/desc_sat.h>
63
64 #ifdef ENABLE_NLS
65 # include "gettext.h"
66 # include <libintl.h>
67 # define _(string) dgettext(LIBDVBV5_DOMAIN, string)
68
69 #else
70 # define _(string) string
71 #endif
72
73 # define N_(string) string
74
dvb_poll(struct dvb_v5_fe_parms_priv * parms,int fd,unsigned int seconds)75 static int dvb_poll(struct dvb_v5_fe_parms_priv *parms, int fd, unsigned int seconds)
76 {
77 fd_set set;
78 struct timeval timeout;
79 int ret;
80
81 /* Initialize the file descriptor set. */
82 FD_ZERO (&set);
83 FD_SET (fd, &set);
84
85 /* Initialize the timeout data structure. */
86 timeout.tv_sec = seconds;
87 timeout.tv_usec = 0;
88
89 /* `select' logfuncreturns 0 if timeout, 1 if input available, -1 if error. */
90 do ret = select (FD_SETSIZE, &set, NULL, NULL, &timeout);
91 while (!parms->p.abort && ret == -1 && errno == EINTR);
92
93 return ret;
94 }
95
dvb_read_section(struct dvb_v5_fe_parms * parms,int dmx_fd,unsigned char tid,uint16_t pid,void ** table,unsigned timeout)96 int dvb_read_section(struct dvb_v5_fe_parms *parms, int dmx_fd,
97 unsigned char tid, uint16_t pid, void **table,
98 unsigned timeout)
99 {
100 return dvb_read_section_with_id(parms, dmx_fd, tid, pid, -1, table, timeout);
101 }
102
103 /*
104 * The code below was inspired on Linux Kernel's bitmask implementation
105 */
106
107 #define BITS_PER_LONG (8 * sizeof(long))
108 #define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
109 #define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
110 #define BITS_TO_LONGS(nr) ((nr +BITS_PER_LONG - 1) / BITS_PER_LONG)
111
set_bit(int nr,unsigned long * addr)112 static void set_bit(int nr, unsigned long *addr)
113 {
114 unsigned long mask = BIT_MASK(nr);
115 unsigned long *p = addr + BIT_WORD(nr);
116
117 *p |= mask;
118 }
119
test_bit(int nr,unsigned long * addr)120 static int test_bit(int nr, unsigned long *addr)
121 {
122 unsigned long mask = BIT_MASK(nr);
123 unsigned long *p = addr + BIT_WORD(nr);
124
125 return (*p & mask) ? -1 : 0;
126 }
127
is_all_bits_set(int nr,unsigned long * addr)128 static int is_all_bits_set(int nr, unsigned long *addr)
129 {
130 unsigned long mask = BIT_MASK(nr + 1) - 1;
131
132 return (*addr == mask);
133 }
134
135
136 struct dvb_table_filter_ext_priv {
137 int last_section;
138 unsigned long is_read_bits[BITS_TO_LONGS(256)];
139
140 /* section gaps and multiple ts_id handling */
141 int ext_id;
142 int first_section;
143 int done;
144 };
145
146 struct dvb_table_filter_priv {
147 int num_extensions;
148 struct dvb_table_filter_ext_priv *extensions;
149 };
150
dvb_parse_section_alloc(struct dvb_v5_fe_parms_priv * parms,struct dvb_table_filter * sect)151 static int dvb_parse_section_alloc(struct dvb_v5_fe_parms_priv *parms,
152 struct dvb_table_filter *sect)
153 {
154 struct dvb_table_filter_priv *priv;
155
156 if (!sect->table) {
157 dvb_logerr(_("%s: table memory pointer not filled"),
158 __func__);
159 return -4;
160 }
161 *sect->table = NULL;
162 priv = calloc(sizeof(struct dvb_table_filter_priv), 1);
163 if (!priv) {
164 dvb_logerr(_("%s: out of memory"), __func__);
165 return -1;
166 }
167 sect->priv = priv;
168
169 return 0;
170 }
171
dvb_table_filter_free(struct dvb_table_filter * sect)172 void dvb_table_filter_free(struct dvb_table_filter *sect)
173 {
174 struct dvb_table_filter_priv *priv = sect->priv;
175
176 if (priv) {
177 free (priv->extensions);
178 free(priv);
179 sect->priv = NULL;
180 }
181 }
182
dvb_parse_section(struct dvb_v5_fe_parms_priv * parms,struct dvb_table_filter * sect,const uint8_t * buf,ssize_t buf_length)183 static int dvb_parse_section(struct dvb_v5_fe_parms_priv *parms,
184 struct dvb_table_filter *sect,
185 const uint8_t *buf, ssize_t buf_length)
186 {
187 struct dvb_table_header h;
188 struct dvb_table_filter_priv *priv;
189 struct dvb_table_filter_ext_priv *ext;
190 unsigned char tid;
191 int i = 0, new = 0;
192
193 memcpy(&h, buf, sizeof(struct dvb_table_header));
194 dvb_table_header_init(&h);
195
196 if (parms->p.verbose)
197 dvb_log(_("%s: received table 0x%02x, extension ID 0x%04x, section %d/%d"),
198 __func__, h.table_id, h.id, h.section_id, h.last_section);
199
200 if (sect->tid != h.table_id) {
201 dvb_logdbg(_("%s: couldn't match ID %d at the active section filters"),
202 __func__, h.table_id);
203 return -1;
204 }
205 priv = sect->priv;
206 ext = priv->extensions;
207 tid = h.table_id;
208
209 if (!ext) {
210 ext = calloc(sizeof(struct dvb_table_filter_ext_priv), 1);
211 if (!ext) {
212 dvb_logerr(_("%s: out of memory"), __func__);
213 return -1;
214 }
215 ext->ext_id = h.id;
216 ext->first_section = h.section_id;
217 ext->last_section = h.last_section;
218 priv->extensions = ext;
219 priv->num_extensions = 1;
220 new = 1;
221 } else {
222 /* search for an specific TS ID */
223 if (sect->ts_id != -1) {
224 if (h.id != sect->ts_id)
225 return 0;
226 }
227
228 for (i = 0; i < priv->num_extensions; i++, ext++) {
229 if (ext->ext_id == h.id)
230 break;
231 }
232 if (i == priv->num_extensions) {
233 priv->num_extensions++;
234 priv->extensions = realloc(priv->extensions, sizeof(struct dvb_table_filter_ext_priv) * (priv->num_extensions));
235 ext = priv->extensions;
236 if (!ext) {
237 dvb_logerr(_("%s: out of memory"), __func__);
238 return -1;
239 }
240 ext += i;
241 memset(ext, 0, sizeof(struct dvb_table_filter_ext_priv));
242 ext->ext_id = h.id;
243 ext->first_section = h.section_id;
244 ext->last_section = h.last_section;
245 new = 1;
246 }
247 }
248
249 if (!new) { /* Check if the table was already parsed, but not on first pass */
250 if(ext->done) {
251 if (parms->p.verbose)
252 dvb_log(_("%s: extension already done, ignoring: 0x%04x"), __func__, ext->ext_id);
253 return 0;
254 }
255
256 if (!sect->allow_section_gaps && sect->ts_id == -1) {
257 if (test_bit(h.section_id, ext->is_read_bits))
258 return 0;
259 } else if (ext->ext_id == h.id && ext->first_section == h.section_id) {
260 /* tables like EIT can increment sections by gaps > 1.
261 * in this case, reading is done when a already read
262 * table is reached.
263 */
264 if (parms->p.verbose)
265 dvb_log(_("%s: section repeated on table 0x%02x, extension ID 0x%04x, section %d/%d: done"),
266 __func__, h.table_id, ext->ext_id, h.section_id, h.last_section);
267
268 ext->done = 1;
269
270 goto ret;
271 }
272 }
273
274 /* handle the sections */
275 if (!sect->allow_section_gaps && sect->ts_id == -1)
276 set_bit(h.section_id, ext->is_read_bits);
277
278 if (dvb_table_initializers[tid])
279 dvb_table_initializers[tid](&parms->p, buf,
280 buf_length - DVB_CRC_SIZE,
281 sect->table);
282 else
283 dvb_logerr(_("%s: no initializer for table %d"),
284 __func__, tid);
285
286 if (!sect->allow_section_gaps && sect->ts_id == -1 &&
287 is_all_bits_set(ext->last_section, ext->is_read_bits)) {
288 if (parms->p.verbose)
289 dvb_log(_("%s: table 0x%02x, extension ID 0x%04x: done"),
290 __func__, h.table_id, h.id);
291 ext->done = 1;
292 }
293
294 if (!ext->done)
295 return 0;
296
297 ret:
298 /* Check if all extensions are done */
299 for (ext = priv->extensions, i = 0; i < priv->num_extensions; i++, ext++) {
300 if (!ext->done) {
301 if (parms->p.verbose)
302 dvb_log(_("%s: extension not completed yet: 0x%04x"),
303 __func__, ext->ext_id);
304 return 0;
305 }
306 }
307
308 /* Section was fully parsed */
309 return 1;
310 }
311
dvb_read_sections(struct dvb_v5_fe_parms * __p,int dmx_fd,struct dvb_table_filter * sect,unsigned timeout)312 int dvb_read_sections(struct dvb_v5_fe_parms *__p, int dmx_fd,
313 struct dvb_table_filter *sect,
314 unsigned timeout)
315 {
316 struct dvb_v5_fe_parms_priv *parms = (void *)__p;
317 int ret;
318 uint8_t *buf = NULL;
319 uint8_t mask = 0xff;
320
321 ret = dvb_parse_section_alloc(parms, sect);
322 if (ret < 0)
323 return ret;
324
325 if (dvb_set_section_filter(dmx_fd, sect->pid, 1,
326 §->tid, &mask, NULL,
327 DMX_IMMEDIATE_START | DMX_CHECK_CRC)) {
328 dvb_dmx_stop(dmx_fd);
329 return -1;
330 }
331 if (parms->p.verbose)
332 dvb_log(_("%s: waiting for table ID 0x%02x, program ID 0x%02x"),
333 __func__, sect->tid, sect->pid);
334
335 buf = calloc(DVB_MAX_PAYLOAD_PACKET_SIZE, 1);
336 if (!buf) {
337 dvb_logerr(_("%s: out of memory"), __func__);
338 dvb_dmx_stop(dmx_fd);
339 dvb_table_filter_free(sect);
340 return -1;
341 }
342
343
344 do {
345 int available;
346 uint32_t crc;
347 ssize_t buf_length = 0;
348
349 do {
350 available = dvb_poll(parms, dmx_fd, timeout);
351 } while (available < 0 && errno == EOVERFLOW);
352
353 if (parms->p.abort) {
354 ret = 0;
355 break;
356 }
357 if (available <= 0) {
358 dvb_logerr(_("%s: no data read on section filter"), __func__);
359 ret = -1;
360 break;
361 }
362 buf_length = read(dmx_fd, buf, DVB_MAX_PAYLOAD_PACKET_SIZE);
363
364 if (!buf_length) {
365 dvb_logerr(_("%s: buf returned an empty buffer"), __func__);
366 ret = -1;
367 break;
368 }
369 if (buf_length < 0) {
370 dvb_perror(_("dvb_read_section: read error"));
371 ret = -2;
372 break;
373 }
374
375 crc = dvb_crc32(buf, buf_length, 0xFFFFFFFF);
376 if (crc != 0) {
377 dvb_logerr(_("%s: crc error"), __func__);
378 ret = -3;
379 break;
380 }
381
382 ret = dvb_parse_section(parms, sect, buf, buf_length);
383 } while (!ret);
384 free(buf);
385 dvb_dmx_stop(dmx_fd);
386 dvb_table_filter_free(sect);
387
388 if (ret > 0)
389 ret = 0;
390
391 return ret;
392 }
393
dvb_read_section_with_id(struct dvb_v5_fe_parms * parms,int dmx_fd,unsigned char tid,uint16_t pid,int ts_id,void ** table,unsigned timeout)394 int dvb_read_section_with_id(struct dvb_v5_fe_parms *parms, int dmx_fd,
395 unsigned char tid, uint16_t pid,
396 int ts_id,
397 void **table, unsigned timeout)
398 {
399 struct dvb_table_filter tab;
400
401 tab.tid = tid;
402 tab.pid = pid;
403 tab.ts_id = ts_id;
404 tab.table = table;
405 tab.allow_section_gaps = 0;
406
407 return dvb_read_sections(parms, dmx_fd, &tab, timeout);
408 }
409
dvb_scan_alloc_handler_table(uint32_t delivery_system)410 struct dvb_v5_descriptors *dvb_scan_alloc_handler_table(uint32_t delivery_system)
411 {
412 struct dvb_v5_descriptors *dvb_scan_handler;
413
414 dvb_scan_handler = calloc(sizeof(*dvb_scan_handler), 1);
415 if (!dvb_scan_handler)
416 return NULL;
417
418 dvb_scan_handler->delivery_system = delivery_system;
419
420 return dvb_scan_handler;
421 }
422
dvb_scan_free_handler_table(struct dvb_v5_descriptors * dvb_scan_handler)423 void dvb_scan_free_handler_table(struct dvb_v5_descriptors *dvb_scan_handler)
424 {
425 int i;
426
427 if (!dvb_scan_handler)
428 return;
429
430 if (dvb_scan_handler->pat)
431 dvb_table_pat_free(dvb_scan_handler->pat);
432 if (dvb_scan_handler->vct)
433 atsc_table_vct_free(dvb_scan_handler->vct);
434 if (dvb_scan_handler->nit)
435 dvb_table_nit_free(dvb_scan_handler->nit);
436 if (dvb_scan_handler->sdt)
437 dvb_table_sdt_free(dvb_scan_handler->sdt);
438 if (dvb_scan_handler->program) {
439 for (i = 0; i < dvb_scan_handler->num_program; i++)
440 if (dvb_scan_handler->program[i].pmt)
441 dvb_table_pmt_free(dvb_scan_handler->program[i].pmt);
442 free(dvb_scan_handler->program);
443 }
444
445 free(dvb_scan_handler);
446 }
447
dvb_get_ts_tables(struct dvb_v5_fe_parms * __p,int dmx_fd,uint32_t delivery_system,unsigned other_nit,unsigned timeout_multiply)448 struct dvb_v5_descriptors *dvb_get_ts_tables(struct dvb_v5_fe_parms *__p,
449 int dmx_fd,
450 uint32_t delivery_system,
451 unsigned other_nit,
452 unsigned timeout_multiply)
453 {
454 struct dvb_v5_fe_parms_priv *parms = (void *)__p;
455 int rc;
456 unsigned pat_pmt_time, sdt_time, nit_time, vct_time;
457 int atsc_filter = 0;
458 unsigned num_pmt = 0;
459
460 struct dvb_v5_descriptors *dvb_scan_handler;
461
462 dvb_scan_handler = dvb_scan_alloc_handler_table(delivery_system);
463 if (!dvb_scan_handler)
464 return NULL;
465
466 if (!timeout_multiply)
467 timeout_multiply = 1;
468
469 /* Get standard timeouts for each table */
470 switch(delivery_system) {
471 case SYS_DVBC_ANNEX_A:
472 case SYS_DVBC_ANNEX_C:
473 case SYS_DVBS:
474 case SYS_DVBS2:
475 case SYS_TURBO:
476 pat_pmt_time = 1;
477 sdt_time = 2;
478 nit_time = 10;
479 break;
480 case SYS_DVBT:
481 case SYS_DVBT2:
482 pat_pmt_time = 1;
483 sdt_time = 2;
484 nit_time = 12;
485 break;
486 case SYS_ISDBT:
487 pat_pmt_time = 1;
488 sdt_time = 2;
489 nit_time = 12;
490 break;
491 case SYS_ATSC:
492 atsc_filter = ATSC_TABLE_TVCT;
493 pat_pmt_time = 2;
494 vct_time = 2;
495 sdt_time = 5;
496 nit_time = 5;
497 break;
498 case SYS_DVBC_ANNEX_B:
499 atsc_filter = ATSC_TABLE_CVCT;
500 pat_pmt_time = 2;
501 vct_time = 2;
502 sdt_time = 5;
503 nit_time = 5;
504 break;
505 default:
506 pat_pmt_time = 1;
507 sdt_time = 2;
508 nit_time = 10;
509 break;
510 };
511
512 /* PAT table */
513 rc = dvb_read_section(&parms->p, dmx_fd,
514 DVB_TABLE_PAT, DVB_TABLE_PAT_PID,
515 (void **)&dvb_scan_handler->pat,
516 pat_pmt_time * timeout_multiply);
517 if (parms->p.abort)
518 return dvb_scan_handler;
519 if (rc < 0) {
520 dvb_logerr(_("error while waiting for PAT table"));
521 dvb_scan_free_handler_table(dvb_scan_handler);
522 return NULL;
523 }
524 if (parms->p.verbose)
525 dvb_table_pat_print(&parms->p, dvb_scan_handler->pat);
526
527 /* ATSC-specific VCT table */
528 if (atsc_filter) {
529 rc = dvb_read_section(&parms->p, dmx_fd,
530 atsc_filter, ATSC_TABLE_VCT_PID,
531 (void **)&dvb_scan_handler->vct,
532 vct_time * timeout_multiply);
533 if (parms->p.abort)
534 return dvb_scan_handler;
535 if (rc < 0)
536 dvb_logerr(_("error while waiting for VCT table"));
537 else if (parms->p.verbose)
538 atsc_table_vct_print(&parms->p, dvb_scan_handler->vct);
539 }
540
541 /* PMT tables */
542 dvb_scan_handler->program = calloc(dvb_scan_handler->pat->programs,
543 sizeof(*dvb_scan_handler->program));
544
545 dvb_pat_program_foreach(program, dvb_scan_handler->pat) {
546 dvb_scan_handler->program[num_pmt].pat_pgm = program;
547
548 if (!program->service_id) {
549 if (parms->p.verbose)
550 dvb_log(_("Program #%d is network PID: 0x%04x"),
551 num_pmt, program->pid);
552 num_pmt++;
553 continue;
554 }
555 if (parms->p.verbose)
556 dvb_log(_("Program #%d ID 0x%04x, service ID 0x%04x"),
557 num_pmt, program->pid, program->service_id);
558 rc = dvb_read_section(&parms->p, dmx_fd,
559 DVB_TABLE_PMT, program->pid,
560 (void **)&dvb_scan_handler->program[num_pmt].pmt,
561 pat_pmt_time * timeout_multiply);
562 if (parms->p.abort) {
563 dvb_scan_handler->num_program = num_pmt + 1;
564 return dvb_scan_handler;
565 }
566 if (rc < 0) {
567 dvb_logerr(_("error while reading the PMT table for service 0x%04x"),
568 program->service_id);
569 dvb_scan_handler->program[num_pmt].pmt = NULL;
570 } else {
571 if (parms->p.verbose)
572 dvb_table_pmt_print(&parms->p,
573 dvb_scan_handler->program[num_pmt].pmt);
574 }
575 num_pmt++;
576 }
577 dvb_scan_handler->num_program = num_pmt;
578
579 /* NIT table */
580 rc = dvb_read_section(&parms->p, dmx_fd,
581 DVB_TABLE_NIT, DVB_TABLE_NIT_PID,
582 (void **)&dvb_scan_handler->nit,
583 nit_time * timeout_multiply);
584 if (parms->p.abort)
585 return dvb_scan_handler;
586 if (rc < 0)
587 dvb_logerr(_("error while reading the NIT table"));
588 else if (parms->p.verbose)
589 dvb_table_nit_print(&parms->p, dvb_scan_handler->nit);
590
591 /* SDT table */
592 if (!dvb_scan_handler->vct || other_nit) {
593 rc = dvb_read_section(&parms->p, dmx_fd,
594 DVB_TABLE_SDT, DVB_TABLE_SDT_PID,
595 (void **)&dvb_scan_handler->sdt,
596 sdt_time * timeout_multiply);
597 if (parms->p.abort)
598 return dvb_scan_handler;
599 if (rc < 0)
600 dvb_logerr(_("error while reading the SDT table"));
601 else if (parms->p.verbose)
602 dvb_table_sdt_print(&parms->p, dvb_scan_handler->sdt);
603 }
604
605 /* NIT/SDT other tables */
606 if (other_nit) {
607 if (parms->p.verbose)
608 dvb_log(_("Parsing other NIT/SDT"));
609 rc = dvb_read_section(&parms->p, dmx_fd,
610 DVB_TABLE_NIT2, DVB_TABLE_NIT_PID,
611 (void **)&dvb_scan_handler->nit,
612 nit_time * timeout_multiply);
613 if (parms->p.abort)
614 return dvb_scan_handler;
615 if (rc < 0)
616 dvb_logerr(_("error while reading the NIT table"));
617 else if (parms->p.verbose)
618 dvb_table_nit_print(&parms->p, dvb_scan_handler->nit);
619
620 rc = dvb_read_section(&parms->p, dmx_fd,
621 DVB_TABLE_SDT2, DVB_TABLE_SDT_PID,
622 (void **)&dvb_scan_handler->sdt,
623 sdt_time * timeout_multiply);
624 if (parms->p.abort)
625 return dvb_scan_handler;
626 if (rc < 0)
627 dvb_logerr(_("error while reading the SDT table"));
628 else if (parms->p.verbose)
629 dvb_table_sdt_print(&parms->p, dvb_scan_handler->sdt);
630 }
631
632 return dvb_scan_handler;
633 }
634
dvb_scan_transponder(struct dvb_v5_fe_parms * __p,struct dvb_entry * entry,int dmx_fd,check_frontend_t * check_frontend,void * args,unsigned other_nit,unsigned timeout_multiply)635 struct dvb_v5_descriptors *dvb_scan_transponder(struct dvb_v5_fe_parms *__p,
636 struct dvb_entry *entry,
637 int dmx_fd,
638 check_frontend_t *check_frontend,
639 void *args,
640 unsigned other_nit,
641 unsigned timeout_multiply)
642 {
643 struct dvb_v5_fe_parms_priv *parms = (void *)__p;
644 struct dvb_v5_descriptors *dvb_scan_handler = NULL;
645 uint32_t freq, delsys = SYS_UNDEFINED;
646 int i, rc;
647
648 /* First of all, set the delivery system */
649 dvb_retrieve_entry_prop(entry, DTV_DELIVERY_SYSTEM, &delsys);
650 dvb_set_compat_delivery_system(&parms->p, delsys);
651
652 /* Copy data into parms */
653 for (i = 0; i < entry->n_props; i++) {
654 uint32_t data = entry->props[i].u.data;
655
656 /* Don't change the delivery system */
657 if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM)
658 continue;
659
660 dvb_fe_store_parm(&parms->p, entry->props[i].cmd, data);
661
662 if (parms->p.current_sys == SYS_ATSC &&
663 entry->props[i].cmd == DTV_MODULATION) {
664 if (data != VSB_8 && data != VSB_16)
665 dvb_fe_store_parm(&parms->p,
666 DTV_DELIVERY_SYSTEM,
667 SYS_DVBC_ANNEX_B);
668 }
669 }
670
671 rc = dvb_fe_set_parms(&parms->p);
672 if (rc < 0) {
673 dvb_perror(_("dvb_fe_set_parms failed"));
674 return NULL;
675 }
676
677 /* As the DVB core emulates it, better to always use auto */
678 dvb_fe_store_parm(&parms->p, DTV_INVERSION, INVERSION_AUTO);
679
680 dvb_fe_retrieve_parm(&parms->p, DTV_FREQUENCY, &freq);
681 if (parms->p.verbose)
682 dvb_fe_prt_parms(&parms->p);
683
684 rc = check_frontend(args, &parms->p);
685 if (rc < 0)
686 return NULL;
687
688 dvb_scan_handler = dvb_get_ts_tables(&parms->p, dmx_fd,
689 parms->p.current_sys,
690 other_nit,
691 timeout_multiply);
692
693 return dvb_scan_handler;
694 }
695
dvb_estimate_freq_shift(struct dvb_v5_fe_parms * __p)696 int dvb_estimate_freq_shift(struct dvb_v5_fe_parms *__p)
697 {
698 struct dvb_v5_fe_parms_priv *parms = (void *)__p;
699 uint32_t shift = 0, bw = 0, min_bw = 0, symbol_rate, ro;
700 int rolloff = 0;
701 int divisor = 100;
702
703 /* Need to handle only cable/satellite and ATSC standards */
704 switch (parms->p.current_sys) {
705 case SYS_DVBC_ANNEX_A:
706 case SYS_DVBC_ANNEX_C:
707 rolloff = 115;
708 break;
709 case SYS_DVBS:
710 divisor = 100000;
711 rolloff = 135;
712 break;
713 case SYS_DVBS2:
714 case SYS_DSS:
715 case SYS_TURBO:
716 divisor = 100000;
717 dvb_fe_retrieve_parm(&parms->p, DTV_ROLLOFF, &ro);
718 switch (ro) {
719 case ROLLOFF_20:
720 rolloff = 120;
721 break;
722 case ROLLOFF_25:
723 rolloff = 125;
724 break;
725 default:
726 case ROLLOFF_AUTO:
727 case ROLLOFF_35:
728 rolloff = 135;
729 break;
730 }
731 break;
732 case SYS_ATSC:
733 case SYS_DVBC_ANNEX_B:
734 bw = 6000000;
735 break;
736 case SYS_ISDBS:
737 /* since ISDBS uses fixed symbol_rate & rolloff,
738 * those parameters are not mandatory in channel config file.
739 */
740 bw = 28860 * 135 / 100;
741 break;
742 case SYS_DVBT2:
743 min_bw = 1700000;
744 break;
745 case SYS_ISDBT:
746 case SYS_DVBT:
747 case SYS_DTMB:
748 /* FIXME: does it also apply for DTMB? */
749 min_bw = 6000000;
750 break;
751 default:
752 break;
753 }
754 if (rolloff) {
755 /*
756 * This is not 100% correct for DVB-S2, as there is a bw
757 * guard interval there but it should be enough for the
758 * purposes of estimating a max frequency shift here.
759 */
760 dvb_fe_retrieve_parm(&parms->p, DTV_SYMBOL_RATE, &symbol_rate);
761 bw = (symbol_rate * rolloff) / divisor;
762 }
763 if (!bw)
764 dvb_fe_retrieve_parm(&parms->p, DTV_BANDWIDTH_HZ, &bw);
765 if (!bw)
766 bw = min_bw;
767 if (!bw)
768 dvb_log(_("Cannot calc frequency shift. " \
769 "Either bandwidth/symbol-rate is unavailable (yet)."));
770 /*
771 * If the max frequency shift between two frequencies is below
772 * than the used bandwidth / 8, it should be the same channel.
773 */
774 shift = bw / 8;
775
776 return shift;
777 }
778
dvb_new_freq_is_needed(struct dvb_entry * entry,struct dvb_entry * last_entry,uint32_t freq,enum dvb_sat_polarization pol,int shift)779 int dvb_new_freq_is_needed(struct dvb_entry *entry, struct dvb_entry *last_entry,
780 uint32_t freq, enum dvb_sat_polarization pol, int shift)
781 {
782 return dvb_new_entry_is_needed(entry, last_entry, freq, shift,
783 pol, NO_STREAM_ID_FILTER);
784 }
785
dvb_scan_add_entry(struct dvb_v5_fe_parms * __p,struct dvb_entry * first_entry,struct dvb_entry * entry,uint32_t freq,uint32_t shift,enum dvb_sat_polarization pol)786 struct dvb_entry *dvb_scan_add_entry(struct dvb_v5_fe_parms *__p,
787 struct dvb_entry *first_entry,
788 struct dvb_entry *entry,
789 uint32_t freq, uint32_t shift,
790 enum dvb_sat_polarization pol)
791 {
792 return dvb_scan_add_entry_ex(__p, first_entry, entry, freq, shift,
793 pol, NO_STREAM_ID_FILTER);
794 }
795
dvb_new_entry_is_needed(struct dvb_entry * entry,struct dvb_entry * last_entry,uint32_t freq,int shift,enum dvb_sat_polarization pol,uint32_t stream_id)796 int dvb_new_entry_is_needed(struct dvb_entry *entry,
797 struct dvb_entry *last_entry,
798 uint32_t freq, int shift,
799 enum dvb_sat_polarization pol, uint32_t stream_id)
800 {
801 for (; entry != last_entry; entry = entry->next) {
802 int i;
803
804 for (i = 0; i < entry->n_props; i++) {
805 uint32_t data = entry->props[i].u.data;
806
807 if (entry->props[i].cmd == DTV_FREQUENCY) {
808 if (freq < data - shift || freq > data + shift)
809 break;
810 }
811 if (pol != POLARIZATION_OFF
812 && entry->props[i].cmd == DTV_POLARIZATION) {
813 if (data != pol)
814 break;
815 }
816 /* NO_STREAM_ID_FILTER: stream_id is not used.
817 * 0: unspecified/auto. libdvbv5 default value.
818 */
819 if (stream_id != NO_STREAM_ID_FILTER && stream_id != 0
820 && entry->props[i].cmd == DTV_STREAM_ID) {
821 if (data != stream_id)
822 break;
823 }
824 }
825 if (i == entry->n_props && entry->n_props > 0)
826 return 0;
827 }
828
829 return 1;
830 }
831
dvb_scan_add_entry_ex(struct dvb_v5_fe_parms * __p,struct dvb_entry * first_entry,struct dvb_entry * entry,uint32_t freq,uint32_t shift,enum dvb_sat_polarization pol,uint32_t stream_id)832 struct dvb_entry *dvb_scan_add_entry_ex(struct dvb_v5_fe_parms *__p,
833 struct dvb_entry *first_entry,
834 struct dvb_entry *entry,
835 uint32_t freq, uint32_t shift,
836 enum dvb_sat_polarization pol,
837 uint32_t stream_id)
838 {
839 struct dvb_v5_fe_parms_priv *parms = (void *)__p;
840 struct dvb_entry *new_entry;
841 int i, n = 2;
842
843 if (!dvb_new_entry_is_needed(first_entry, NULL, freq, shift, pol,
844 stream_id))
845 return NULL;
846
847 /* Clone the current entry into a new entry */
848 new_entry = calloc(sizeof(*new_entry), 1);
849 if (!new_entry) {
850 dvb_perror(_("not enough memory for a new scanning frequency/TS"));
851 return NULL;
852 }
853
854 /*
855 * We can't just copy the entire entry struct, as some strings
856 * like lnb, channel, vchannel will be freed multiple times.
857 * So, copy the props and the Satellite parameters only.
858 */
859 memcpy(new_entry->props, entry->props, sizeof(entry->props));
860 new_entry->n_props = entry->n_props;
861 new_entry->sat_number = entry->sat_number;
862 new_entry->freq_bpf = entry->freq_bpf;
863 new_entry->diseqc_wait = entry->diseqc_wait;
864 if (entry->lnb)
865 new_entry->lnb = strdup(entry->lnb);
866
867 /*
868 * The frequency should change to the new one. Seek for it and
869 * replace its value to the desired one.
870 */
871 for (i = 0; i < new_entry->n_props; i++) {
872 if (new_entry->props[i].cmd == DTV_FREQUENCY) {
873 new_entry->props[i].u.data = freq;
874 /* Navigate to the end of the entry list */
875 while (entry->next) {
876 entry = entry->next;
877 n++;
878 }
879 dvb_log(_("New transponder/channel found: #%d: %d"),
880 n, freq);
881 entry->next = new_entry;
882 new_entry->next = NULL;
883 return new_entry;
884 }
885 }
886
887 /* This should never happen */
888 dvb_logerr(_("BUG: Couldn't add %d to the scan frequency list."), freq);
889 free(new_entry);
890
891 return NULL;
892 }
893
894 struct update_transponders {
895 struct dvb_v5_fe_parms *parms;
896 struct dvb_v5_descriptors *dvb_scan_handler;
897 struct dvb_entry *first_entry;
898 struct dvb_entry *entry;
899 uint32_t update;
900 enum dvb_sat_polarization pol;
901 uint32_t shift;
902 };
903
add_update_nit_dvbc(struct dvb_table_nit * nit,struct dvb_table_nit_transport * tran,struct dvb_desc * desc,void * priv)904 static void add_update_nit_dvbc(struct dvb_table_nit *nit,
905 struct dvb_table_nit_transport *tran,
906 struct dvb_desc *desc,
907 void *priv)
908 {
909 struct update_transponders *tr = priv;
910 struct dvb_entry *new;
911 struct dvb_desc_cable_delivery *d = (void *)desc;
912
913 if (tr->update) {
914 uint32_t freq;
915 dvb_fe_retrieve_parm(tr->parms, DTV_FREQUENCY, &freq);
916
917 if (freq != d->frequency)
918 return;
919 new = tr->entry;
920 } else {
921 new = dvb_scan_add_entry(tr->parms, tr->first_entry, tr->entry,
922 d->frequency, tr->shift, tr->pol);
923 if (!new)
924 return;
925 }
926
927 /* Set NIT props for the transponder */
928 dvb_store_entry_prop(new, DTV_MODULATION,
929 dvbc_modulation_table[d->modulation]);
930 dvb_store_entry_prop(new, DTV_SYMBOL_RATE, d->symbol_rate);
931 dvb_store_entry_prop(new, DTV_INNER_FEC, dvbc_fec_table[d->fec_inner]);
932
933 }
934
add_update_nit_isdbt(struct dvb_table_nit * nit,struct dvb_table_nit_transport * tran,struct dvb_desc * desc,void * priv)935 static void add_update_nit_isdbt(struct dvb_table_nit *nit,
936 struct dvb_table_nit_transport *tran,
937 struct dvb_desc *desc,
938 void *priv)
939 {
940 struct update_transponders *tr = priv;
941 struct dvb_entry *new;
942 struct isdbt_desc_terrestrial_delivery_system *d = (void *)desc;
943 int i;
944
945 if (tr->update) {
946 uint32_t mode = isdbt_mode[d->transmission_mode];
947 uint32_t guard = isdbt_interval[d->guard_interval];
948
949 dvb_store_entry_prop(tr->entry, DTV_TRANSMISSION_MODE, mode);
950 dvb_store_entry_prop(tr->entry, DTV_GUARD_INTERVAL, guard);
951 return;
952 }
953
954 for (i = 0; i < d->num_freqs; i++) {
955 new = dvb_scan_add_entry(tr->parms, tr->first_entry, tr->entry,
956 d->frequency[i], tr->shift, tr->pol);
957 if (!new)
958 return;
959 }
960 }
961
add_update_nit_1seg(struct dvb_table_nit * nit,struct dvb_table_nit_transport * tran,struct dvb_desc * desc,void * priv)962 static void add_update_nit_1seg(struct dvb_table_nit *nit,
963 struct dvb_table_nit_transport *tran,
964 struct dvb_desc *desc,
965 void *priv)
966 {
967 struct update_transponders *tr = priv;
968 struct isdb_desc_partial_reception *d = (void *)desc;
969 size_t len;
970 int i;
971
972 if (!tr->update)
973 return;
974
975 len = d->length / sizeof(*d->partial_reception);
976
977 for (i = 0; i < len; i++) {
978 if (tr->entry->service_id == d->partial_reception[i].service_id) {
979 dvb_store_entry_prop(tr->entry,
980 DTV_ISDBT_PARTIAL_RECEPTION, 1);
981 return;
982 }
983 }
984 dvb_store_entry_prop(tr->entry, DTV_ISDBT_PARTIAL_RECEPTION, 0);
985 }
986
add_update_nit_dvbt2(struct dvb_table_nit * nit,struct dvb_table_nit_transport * tran,struct dvb_desc * desc,void * priv)987 static void add_update_nit_dvbt2(struct dvb_table_nit *nit,
988 struct dvb_table_nit_transport *tran,
989 struct dvb_desc *desc,
990 void *priv)
991 {
992 struct update_transponders *tr = priv;
993 struct dvb_entry *new;
994 struct dvb_extension_descriptor *d = (void *)desc;
995 struct dvb_desc_t2_delivery *t2 = (void *)d->descriptor;
996 int i;
997
998 if (d->extension_code != T2_delivery_system_descriptor)
999 return;
1000
1001 if (tr->update) {
1002 uint32_t freq;
1003 dvb_fe_retrieve_parm(tr->parms, DTV_FREQUENCY, &freq);
1004
1005 if (tr->entry->service_id != t2->system_id)
1006 return;
1007
1008 dvb_store_entry_prop(tr->entry, DTV_DELIVERY_SYSTEM,
1009 SYS_DVBT2);
1010 dvb_store_entry_prop(tr->entry, DTV_STREAM_ID,
1011 t2->plp_id);
1012
1013 if (d->length -1 <= 4)
1014 return;
1015
1016 dvb_store_entry_prop(tr->entry, DTV_BANDWIDTH_HZ,
1017 dvbt2_bw[t2->bandwidth]);
1018 dvb_store_entry_prop(tr->entry, DTV_GUARD_INTERVAL,
1019 dvbt2_interval[t2->guard_interval]);
1020 dvb_store_entry_prop(tr->entry, DTV_TRANSMISSION_MODE,
1021 dvbt2_transmission_mode[t2->transmission_mode]);
1022
1023 return;
1024 }
1025
1026 if (d->length -1 <= 4)
1027 return;
1028
1029 for (i = 0; i < t2->frequency_loop_length; i++) {
1030 new = dvb_scan_add_entry_ex(tr->parms,
1031 tr->first_entry, tr->entry,
1032 t2->centre_frequency[i] * 10,
1033 tr->shift, tr->pol, t2->plp_id);
1034 if (!new)
1035 continue;
1036
1037 dvb_store_entry_prop(new, DTV_DELIVERY_SYSTEM,
1038 SYS_DVBT2);
1039 dvb_store_entry_prop(new, DTV_STREAM_ID,
1040 t2->plp_id);
1041 dvb_store_entry_prop(new, DTV_BANDWIDTH_HZ,
1042 dvbt2_bw[t2->bandwidth]);
1043 dvb_store_entry_prop(new, DTV_GUARD_INTERVAL,
1044 dvbt2_interval[t2->guard_interval]);
1045 dvb_store_entry_prop(new, DTV_TRANSMISSION_MODE,
1046 dvbt2_transmission_mode[t2->transmission_mode]);
1047 }
1048 }
1049
add_update_nit_dvbt(struct dvb_table_nit * nit,struct dvb_table_nit_transport * tran,struct dvb_desc * desc,void * priv)1050 static void add_update_nit_dvbt(struct dvb_table_nit *nit,
1051 struct dvb_table_nit_transport *tran,
1052 struct dvb_desc *desc,
1053 void *priv)
1054 {
1055 struct update_transponders *tr = priv;
1056 struct dvb_entry *new;
1057 struct dvb_desc_terrestrial_delivery *d = (void *)desc;
1058
1059 if (tr->update)
1060 return;
1061
1062 new = dvb_scan_add_entry(tr->parms, tr->first_entry, tr->entry,
1063 d->centre_frequency * 10, tr->shift, tr->pol);
1064 if (!new)
1065 return;
1066
1067 /* Set NIT DVB-T props for the transponder */
1068 dvb_store_entry_prop(new, DTV_MODULATION,
1069 dvbt_modulation[d->constellation]);
1070 dvb_store_entry_prop(new, DTV_BANDWIDTH_HZ,
1071 dvbt_bw[d->bandwidth]);
1072 dvb_store_entry_prop(new, DTV_CODE_RATE_HP,
1073 dvbt_code_rate[d->code_rate_hp_stream]);
1074 dvb_store_entry_prop(new, DTV_CODE_RATE_LP,
1075 dvbt_code_rate[d->code_rate_lp_stream]);
1076 dvb_store_entry_prop(new, DTV_GUARD_INTERVAL,
1077 dvbt_interval[d->guard_interval]);
1078 dvb_store_entry_prop(new, DTV_TRANSMISSION_MODE,
1079 dvbt_transmission_mode[d->transmission_mode]);
1080 dvb_store_entry_prop(new, DTV_HIERARCHY,
1081 dvbt_hierarchy[d->hierarchy_information]);
1082 }
1083
add_update_nit_dvbs(struct dvb_table_nit * nit,struct dvb_table_nit_transport * tran,struct dvb_desc * desc,void * priv)1084 static void add_update_nit_dvbs(struct dvb_table_nit *nit,
1085 struct dvb_table_nit_transport *tran,
1086 struct dvb_desc *desc,
1087 void *priv)
1088 {
1089 struct update_transponders *tr = priv;
1090 struct dvb_entry *new;
1091 struct dvb_desc_sat *d = (void *)desc;
1092
1093 if (tr->update) {
1094 uint32_t freq;
1095
1096 dvb_fe_retrieve_parm(tr->parms, DTV_FREQUENCY, &freq);
1097 if (freq != d->frequency)
1098 return;
1099 new = tr->entry;
1100 } else {
1101 new = dvb_scan_add_entry(tr->parms, tr->first_entry, tr->entry,
1102 d->frequency, tr->shift, tr->pol);
1103 if (!new)
1104 return;
1105 }
1106
1107 /* Set NIT DVB-S props for the transponder */
1108
1109 dvb_store_entry_prop(new, DTV_MODULATION,
1110 dvbs_modulation[d->modulation_system]);
1111 dvb_store_entry_prop(new, DTV_POLARIZATION,
1112 dvbs_polarization[d->polarization]);
1113 dvb_store_entry_prop(new, DTV_SYMBOL_RATE,
1114 d->symbol_rate);
1115 dvb_store_entry_prop(new, DTV_INNER_FEC,
1116 dvbs_dvbc_dvbs_freq_inner[d->fec]);
1117 dvb_store_entry_prop(new, DTV_ROLLOFF,
1118 dvbs_rolloff[d->roll_off]);
1119
1120 /*
1121 * Check if the returned parameters are really DVB-S or not
1122 *
1123 * DVB-S supports only 0.35 roll-off, with QPSK and
1124 * Red-Solomon FEC 1/2, 2/3, 3/4, 5/6, 7/8. If anythign else is
1125 * reported, then it is DVB-S2.
1126 */
1127
1128 if ((d->roll_off != 0 && d->roll_off != ROLLOFF_35) ||
1129 (d->modulation_system != 0 && d->modulation_system != QPSK)) {
1130 dvb_store_entry_prop(new, DTV_DELIVERY_SYSTEM, SYS_DVBS2);
1131 return;
1132 }
1133
1134 switch (d->fec) {
1135 case FEC_NONE:
1136 case FEC_AUTO:
1137 case FEC_1_2:
1138 case FEC_2_3:
1139 case FEC_3_4:
1140 case FEC_5_6:
1141 case FEC_7_8:
1142 return;
1143 default:
1144 dvb_store_entry_prop(new, DTV_DELIVERY_SYSTEM, SYS_DVBS2);
1145 }
1146 }
1147
add_update_nit_isdbs(struct dvb_table_nit * nit,struct dvb_table_nit_transport * tran,struct dvb_desc * desc,void * priv)1148 static void add_update_nit_isdbs(struct dvb_table_nit *nit,
1149 struct dvb_table_nit_transport *tran,
1150 struct dvb_desc *desc,
1151 void *priv)
1152 {
1153 struct update_transponders *tr = priv;
1154 struct dvb_entry *new;
1155 /* FIXME:
1156 * use the ISDB-S specific satellite delsys descriptor structure,
1157 * instead of overloading to the EN300-468's one, dvb_desc_sat.
1158 * The following members are incompatible:
1159 * {.modulation_type, .modulation_system, .roll_off, .fec}
1160 */
1161 struct dvb_desc_sat *d = (void *)desc;
1162 uint32_t ts_id;
1163
1164 if (tr->update)
1165 return;
1166
1167 ts_id = tran->transport_id;
1168 new = dvb_scan_add_entry_ex(tr->parms, tr->first_entry, tr->entry,
1169 d->frequency, tr->shift, tr->pol, ts_id);
1170 if (!new)
1171 return;
1172
1173 /* Set (optional) ISDB-S props for the transponder */
1174 /* FIXME: fill in other props like DTV_MODULATION, DTV_INNER_FEC.
1175 * This requires extending the enum definitions in DVBv5 API
1176 * to include the ISDB-S/T specific modulation/fec values,
1177 * such as "BPSK" and "look TMCC".
1178 * Since even "AUTO" is not defined, skip setting them now.
1179 */
1180 dvb_store_entry_prop(new, DTV_POLARIZATION,
1181 dvbs_polarization[d->polarization]);
1182 dvb_store_entry_prop(new, DTV_SYMBOL_RATE,
1183 d->symbol_rate);
1184 }
1185
1186
__dvb_add_update_transponders(struct dvb_v5_fe_parms_priv * parms,struct dvb_v5_descriptors * dvb_scan_handler,struct dvb_entry * first_entry,struct dvb_entry * entry,uint32_t update)1187 static void __dvb_add_update_transponders(struct dvb_v5_fe_parms_priv *parms,
1188 struct dvb_v5_descriptors *dvb_scan_handler,
1189 struct dvb_entry *first_entry,
1190 struct dvb_entry *entry,
1191 uint32_t update)
1192 {
1193 struct update_transponders tr = {
1194 .parms = &parms->p,
1195 .dvb_scan_handler = dvb_scan_handler,
1196 .first_entry = first_entry,
1197 .entry = entry,
1198 .update = update,
1199 .pol = POLARIZATION_OFF,
1200 };
1201
1202 if (!dvb_scan_handler->nit)
1203 return;
1204
1205 tr.shift = dvb_estimate_freq_shift(&parms->p);
1206
1207 switch (parms->p.current_sys) {
1208 case SYS_DVBC_ANNEX_A:
1209 case SYS_DVBC_ANNEX_C:
1210 dvb_table_nit_descriptor_handler(
1211 &parms->p, dvb_scan_handler->nit,
1212 cable_delivery_system_descriptor,
1213 NULL, add_update_nit_dvbc, &tr);
1214 return;
1215 case SYS_ISDBT:
1216 dvb_table_nit_descriptor_handler(
1217 &parms->p, dvb_scan_handler->nit,
1218 partial_reception_descriptor,
1219 NULL, add_update_nit_1seg, &tr);
1220 dvb_table_nit_descriptor_handler(&parms->p,
1221 dvb_scan_handler->nit,
1222 ISDBT_delivery_system_descriptor,
1223 NULL, add_update_nit_isdbt, &tr);
1224 return;
1225 case SYS_DVBT:
1226 case SYS_DVBT2:
1227 case SYS_DTMB: /* FIXME: are DTMB nit tables equal to DVB-T? */
1228 dvb_table_nit_descriptor_handler(
1229 &parms->p, dvb_scan_handler->nit,
1230 extension_descriptor,
1231 NULL, add_update_nit_dvbt2, &tr);
1232
1233 dvb_table_nit_descriptor_handler(
1234 &parms->p, dvb_scan_handler->nit,
1235 terrestrial_delivery_system_descriptor,
1236 NULL, add_update_nit_dvbt, &tr);
1237 return;
1238 case SYS_DVBS:
1239 case SYS_DVBS2:
1240 dvb_table_nit_descriptor_handler(
1241 &parms->p, dvb_scan_handler->nit,
1242 satellite_delivery_system_descriptor,
1243 NULL, add_update_nit_dvbs, &tr);
1244 return;
1245 case SYS_ISDBS:
1246 /* see the FIXME: in add_update_nit_isdbs() */
1247 dvb_table_nit_descriptor_handler(
1248 &parms->p, dvb_scan_handler->nit,
1249 satellite_delivery_system_descriptor,
1250 NULL, add_update_nit_isdbs, &tr);
1251 return;
1252
1253 default:
1254 dvb_log(_("Transponders detection not implemented for this standard yet."));
1255 return;
1256 }
1257 }
1258
dvb_add_scaned_transponders(struct dvb_v5_fe_parms * __p,struct dvb_v5_descriptors * dvb_scan_handler,struct dvb_entry * first_entry,struct dvb_entry * entry)1259 void dvb_add_scaned_transponders(struct dvb_v5_fe_parms *__p,
1260 struct dvb_v5_descriptors *dvb_scan_handler,
1261 struct dvb_entry *first_entry,
1262 struct dvb_entry *entry)
1263 {
1264 struct dvb_v5_fe_parms_priv *parms = (void *)__p;
1265
1266 return __dvb_add_update_transponders(parms, dvb_scan_handler,
1267 first_entry, entry, 0);
1268 }
1269
dvb_update_transponders(struct dvb_v5_fe_parms * __p,struct dvb_v5_descriptors * dvb_scan_handler,struct dvb_entry * first_entry,struct dvb_entry * entry)1270 void dvb_update_transponders(struct dvb_v5_fe_parms *__p,
1271 struct dvb_v5_descriptors *dvb_scan_handler,
1272 struct dvb_entry *first_entry,
1273 struct dvb_entry *entry)
1274 {
1275 struct dvb_v5_fe_parms_priv *parms = (void *)__p;
1276
1277 return __dvb_add_update_transponders(parms, dvb_scan_handler,
1278 first_entry, entry, 1);
1279 }
1280