• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 				   &sect->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