1 /*
2  * Copyright (c) 2011-2012 - Mauro Carvalho Chehab
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation version 2.1 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16  * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
17  *
18  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <strings.h> /* strcasecmp */
24 #include <unistd.h>
25 
26 #include "dvb-fe-priv.h"
27 #include <libdvbv5/dvb-file.h>
28 #include <libdvbv5/dvb-v5-std.h>
29 #include <libdvbv5/dvb-scan.h>
30 #include <libdvbv5/dvb-log.h>
31 #include <libdvbv5/descriptors.h>
32 #include <libdvbv5/nit.h>
33 #include <libdvbv5/sdt.h>
34 #include <libdvbv5/pat.h>
35 #include <libdvbv5/pmt.h>
36 #include <libdvbv5/vct.h>
37 #include <libdvbv5/desc_ts_info.h>
38 #include <libdvbv5/desc_logical_channel.h>
39 #include <libdvbv5/desc_language.h>
40 #include <libdvbv5/desc_network_name.h>
41 #include <libdvbv5/desc_cable_delivery.h>
42 #include <libdvbv5/desc_sat.h>
43 #include <libdvbv5/desc_terrestrial_delivery.h>
44 #include <libdvbv5/desc_service.h>
45 #include <libdvbv5/desc_frequency_list.h>
46 #include <libdvbv5/desc_event_short.h>
47 #include <libdvbv5/desc_event_extended.h>
48 #include <libdvbv5/desc_atsc_service_location.h>
49 #include <libdvbv5/desc_hierarchy.h>
50 #include <libdvbv5/countries.h>
51 
52 #include <config.h>
53 
54 #ifdef ENABLE_NLS
55 # include <stdio.h>
56 # include <libintl.h>
57 # define _(string) dgettext(LIBDVBV5_DOMAIN, string)
58 
59 #else
60 # define _(string) string
61 #endif
62 
63 # define N_(string) string
64 
dvb_store_entry_prop(struct dvb_entry * entry,uint32_t cmd,uint32_t value)65 int dvb_store_entry_prop(struct dvb_entry *entry,
66 			 uint32_t cmd, uint32_t value)
67 {
68 	int i;
69 
70 	for (i = 0; i < entry->n_props; i++) {
71 		if (cmd == entry->props[i].cmd)
72 			break;
73 	}
74 	if (i == entry->n_props) {
75 		if (i == DTV_MAX_COMMAND) {
76 			fprintf(stderr, _("Can't add property %s\n"),
77 			       dvb_v5_name[cmd]);
78 			return -1;
79 		}
80 		entry->n_props++;
81 		entry->props[i].cmd = cmd;
82 	}
83 
84 	entry->props[i].u.data = value;
85 
86 	return 0;
87 }
88 
dvb_retrieve_entry_prop(struct dvb_entry * entry,uint32_t cmd,uint32_t * value)89 int dvb_retrieve_entry_prop(struct dvb_entry *entry,
90 			    uint32_t cmd, uint32_t *value)
91 {
92 	int i;
93 
94 	for (i = 0; i < entry->n_props; i++) {
95 		if (cmd == entry->props[i].cmd) {
96 			*value = entry->props[i].u.data;
97 			return 0;
98 		}
99 	}
100 
101 	return -1;
102 }
103 
dvbv5_default_value(int cmd)104 static uint32_t dvbv5_default_value(int cmd)
105 {
106 	switch (cmd) {
107 		case DTV_MODULATION:
108 		case DTV_ISDBT_LAYERA_MODULATION:
109 		case DTV_ISDBT_LAYERB_MODULATION:
110 		case DTV_ISDBT_LAYERC_MODULATION:
111 			return QAM_AUTO;
112 
113 		case DTV_BANDWIDTH_HZ:
114 			return 0;
115 
116 		case DTV_INVERSION:
117 			return INVERSION_AUTO;
118 
119 		case DTV_CODE_RATE_HP:
120 		case DTV_CODE_RATE_LP:
121 		case DTV_INNER_FEC:
122 		case DTV_ISDBT_LAYERA_FEC:
123 		case DTV_ISDBT_LAYERB_FEC:
124 		case DTV_ISDBT_LAYERC_FEC:
125 			return FEC_AUTO;
126 
127 		case DTV_GUARD_INTERVAL:
128 			return GUARD_INTERVAL_AUTO;
129 
130 		case DTV_TRANSMISSION_MODE:
131 			return TRANSMISSION_MODE_AUTO;
132 
133 		case DTV_HIERARCHY:
134 			return HIERARCHY_AUTO;
135 
136 		case DTV_STREAM_ID:
137 			return 0;
138 
139 		case DTV_ISDBT_LAYER_ENABLED:
140 			return 7;
141 
142 		case DTV_ISDBT_PARTIAL_RECEPTION:
143 			return 1;
144 
145 		case DTV_ISDBT_SOUND_BROADCASTING:
146 		case DTV_ISDBT_SB_SUBCHANNEL_ID:
147 		case DTV_ISDBT_SB_SEGMENT_IDX:
148 		case DTV_ISDBT_SB_SEGMENT_COUNT:
149 			return 0;
150 
151 		case DTV_ISDBT_LAYERA_TIME_INTERLEAVING:
152 		case DTV_ISDBT_LAYERB_TIME_INTERLEAVING:
153 		case DTV_ISDBT_LAYERC_TIME_INTERLEAVING:
154 			return INTERLEAVING_AUTO;
155 
156 		case DTV_POLARIZATION:
157 			return POLARIZATION_OFF;
158 
159 		case DTV_ISDBT_LAYERA_SEGMENT_COUNT:
160 			return (uint32_t)-1;
161 
162 		case DTV_ROLLOFF:
163 			return ROLLOFF_AUTO;
164 
165 		case DTV_COUNTRY_CODE:
166 			return COUNTRY_UNKNOWN;
167 
168 		default:
169 			return (uint32_t)-1;
170 	}
171 }
172 
adjust_delsys(struct dvb_entry * entry)173 static void adjust_delsys(struct dvb_entry *entry)
174 {
175 	uint32_t delsys = SYS_UNDEFINED;
176 	const unsigned int *sys_props;
177 	int n;
178 	uint32_t v;
179 
180 	dvb_retrieve_entry_prop(entry, DTV_DELIVERY_SYSTEM, &delsys);
181 	switch (delsys) {
182 	case SYS_ATSC:
183 	case SYS_DVBC_ANNEX_B: {
184 		uint32_t modulation = VSB_8;
185 
186 		dvb_retrieve_entry_prop(entry, DTV_MODULATION, &modulation);
187 		switch (modulation) {
188 		case VSB_8:
189 		case VSB_16:
190 			delsys = SYS_ATSC;
191 			break;
192 		default:
193 			delsys = SYS_DVBC_ANNEX_B;
194 			break;
195 		}
196 		dvb_store_entry_prop(entry, DTV_DELIVERY_SYSTEM, delsys);
197 		break;
198 	}
199 	} /* switch */
200 
201 	/* Fill missing mandatory properties with auto values */
202 
203 	sys_props = dvb_v5_delivery_system[delsys];
204 	if (!sys_props)
205 		return;
206 
207 	n = 0;
208 	while (sys_props[n]) {
209 		if (dvb_retrieve_entry_prop(entry, sys_props[n], &v) == -1) {
210 			dvb_store_entry_prop(entry, sys_props[n], dvbv5_default_value(sys_props[n]));
211 		}
212 		n++;
213 	}
214 }
215 
216 /*
217  * Generic parse function for all formats each channel is contained into
218  * just one line.
219  */
dvb_parse_format_oneline(const char * fname,uint32_t delsys,const struct dvb_parse_file * parse_file)220 struct dvb_file *dvb_parse_format_oneline(const char *fname,
221 					  uint32_t delsys,
222 					  const struct dvb_parse_file *parse_file)
223 {
224 	const char *delimiter = parse_file->delimiter;
225 	const struct dvb_parse_struct *formats = parse_file->formats;
226 	char *buf = NULL, *p;
227 	size_t size = 0;
228 	int len = 0;
229 	int i, j, line = 0;
230 	struct dvb_file *dvb_file;
231 	FILE *fd;
232 	const struct dvb_parse_struct *fmt;
233 	struct dvb_entry *entry = NULL;
234 	const struct dvb_parse_table *table;
235 	char err_msg[80];
236 	int has_inversion;
237 
238 	dvb_file = calloc(sizeof(*dvb_file), 1);
239 	if (!dvb_file) {
240 		perror(_("Allocating memory for dvb_file"));
241 		return NULL;
242 	}
243 
244 	fd = fopen(fname, "r");
245 	if (!fd) {
246 		perror(fname);
247 		free(dvb_file);
248 		return NULL;
249 	}
250 
251 	do {
252 		len = getline(&buf, &size, fd);
253 		if (len <= 0)
254 			break;
255 		line++;
256 
257 		p = buf;
258 		while (*p == ' ')
259 			p++;
260 		if (*p == '\n' || *p == '#' || *p == '\a' || *p == '\0')
261 			continue;
262 
263 		if (parse_file->has_delsys_id) {
264 			p = strtok(p, delimiter);
265 			if (!p) {
266 				sprintf(err_msg, _("unknown delivery system type for %s"),
267 					p);
268 				goto error;
269 			}
270 
271 			/* Parse the type of the delivery system */
272 			for (i = 0; formats[i].id != NULL; i++) {
273 				if (!strcmp(p, formats[i].id))
274 					break;
275 			}
276 			if (!formats[i].id) {
277 				sprintf(err_msg, _("Doesn't know how to handle delimiter '%s'"),
278 					p);
279 				goto error;
280 			}
281 		} else {
282 			/* Seek for the delivery system */
283 			for (i = 0; formats[i].delsys != 0; i++) {
284 				if (formats[i].delsys == delsys)
285 					break;
286 			}
287 			if (!formats[i].delsys) {
288 				sprintf(err_msg, _("Doesn't know how to parse delivery system %d"),
289 					delsys);
290 				goto error;
291 			}
292 		}
293 
294 
295 		fmt = &formats[i];
296 		if (!entry) {
297 			dvb_file->first_entry = calloc(sizeof(*entry), 1);
298 			entry = dvb_file->first_entry;
299 		} else {
300 			entry->next = calloc(sizeof(*entry), 1);
301 			entry = entry->next;
302 		}
303 		entry->sat_number = -1;
304 		entry->props[entry->n_props].cmd = DTV_DELIVERY_SYSTEM;
305 		entry->props[entry->n_props++].u.data = fmt->delsys;
306 		has_inversion = 0;
307 		for (i = 0; i < fmt->size; i++) {
308 			table = &fmt->table[i];
309 			if (delsys && !i) {
310 				p = strtok(p, delimiter);
311 			} else
312 				p = strtok(NULL, delimiter);
313 			if (p && *p == '#')
314 				p = NULL;
315 			if (!p && !fmt->table[i].has_default_value) {
316 				sprintf(err_msg, _("parameter %i (%s) missing"),
317 					i, dvb_cmd_name(table->prop));
318 				goto error;
319 			}
320 			if (p && table->size) {
321 				for (j = 0; j < table->size; j++)
322 					if (!table->table[j] || !strcasecmp(table->table[j], p))
323 						break;
324 				if (j == table->size) {
325 					sprintf(err_msg, _("parameter %s invalid: %s"),
326 						dvb_cmd_name(table->prop), p);
327 					goto error;
328 				}
329 				if (table->prop == DTV_BANDWIDTH_HZ)
330 					j = fe_bandwidth_name[j];
331 				entry->props[entry->n_props].cmd = table->prop;
332                                 entry->props[entry->n_props++].u.data = j;
333 			} else {
334 				long v;
335 
336 				if (!p)
337 					v = fmt->table[i].default_value;
338 				else
339 					v = atol(p);
340 
341 				if (table->mult_factor)
342 					v *= table->mult_factor;
343 
344 				switch (table->prop) {
345 				case DTV_VIDEO_PID:
346 					entry->video_pid = calloc(sizeof(*entry->video_pid), 1);
347 					entry->video_pid_len = 1;
348 					entry->video_pid[0] = v;
349 					break;
350 				case DTV_AUDIO_PID:
351 					entry->audio_pid = calloc(sizeof(*entry->audio_pid), 1);
352 					entry->audio_pid_len = 1;
353 					entry->audio_pid[0] = v;
354 					break;
355 				case DTV_SERVICE_ID:
356 					entry->service_id = v;
357 					break;
358 				case DTV_CH_NAME:
359 					entry->channel = calloc(strlen(p) + 1, 1);
360 					strcpy(entry->channel, p);
361 					break;
362 				default:
363 					entry->props[entry->n_props].cmd = table->prop;
364 					entry->props[entry->n_props++].u.data = v;
365 				}
366 			}
367 			if (table->prop == DTV_INVERSION)
368 				has_inversion = 1;
369 		}
370 		if (!has_inversion) {
371 			entry->props[entry->n_props].cmd = DTV_INVERSION;
372 			entry->props[entry->n_props++].u.data = INVERSION_AUTO;
373 		}
374 		adjust_delsys(entry);
375 	} while (1);
376 	fclose(fd);
377 	if (buf)
378 		free(buf);
379 	return dvb_file;
380 
381 error:
382 	fprintf (stderr, _("ERROR %s while parsing line %d of %s\n"),
383 		 err_msg, line, fname);
384 	dvb_file_free(dvb_file);
385 	fclose(fd);
386 	if (buf)
387 		free(buf);
388 	return NULL;
389 }
390 
get_compat_format(uint32_t delivery_system)391 static uint32_t get_compat_format(uint32_t delivery_system)
392 {
393 	switch (delivery_system) {
394 	case SYS_DVBS:
395 	case SYS_DVBS2:
396 	case SYS_TURBO:
397 	case SYS_ISDBS:
398 	case SYS_DSS:
399 		return SYS_DVBS;
400 	case SYS_ATSC:
401 	case SYS_DVBC_ANNEX_B:
402 		return SYS_ATSC;
403 	case SYS_DVBC_ANNEX_A:
404 	case SYS_DVBC_ANNEX_C:
405 		return  SYS_DVBC_ANNEX_A;
406 	case SYS_CMMB:
407 	case SYS_ISDBT:
408 	case SYS_DVBT:
409 	case SYS_DVBT2:
410 	case SYS_DTMB:
411 		return SYS_DVBT;
412 	default:
413 		return 0;
414 
415 	}
416 }
417 
dvb_write_format_oneline(const char * fname,struct dvb_file * dvb_file,uint32_t delsys,const struct dvb_parse_file * parse_file)418 int dvb_write_format_oneline(const char *fname,
419 			     struct dvb_file *dvb_file,
420 			     uint32_t delsys,
421 			     const struct dvb_parse_file *parse_file)
422 {
423 	const char delimiter = parse_file->delimiter[0];
424 	const struct dvb_parse_struct *formats = parse_file->formats;
425 	int i, j, line = 0, first;
426 	FILE *fp;
427 	const struct dvb_parse_struct *fmt;
428 	struct dvb_entry *entry;
429 	const struct dvb_parse_table *table;
430 	uint32_t data;
431 	char err_msg[80];
432 	uint32_t delsys_compat = 0;
433 
434 	fp = fopen(fname, "w");
435 	if (!fp) {
436 		perror(fname);
437 		return -errno;
438 	}
439 
440 	for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
441 		for (i = 0; i < entry->n_props; i++) {
442 			if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM) {
443 				delsys = entry->props[i].u.data;
444 				break;
445 			}
446 		}
447 
448 		for (i = 0; formats[i].delsys != 0; i++) {
449 			if (formats[i].delsys == delsys)
450 				break;
451 		}
452 		if (!formats[i].delsys) {
453 			delsys_compat = get_compat_format(delsys);
454 			for (i = 0; formats[i].delsys != 0; i++) {
455 				if (formats[i].delsys == delsys_compat) {
456 					delsys = delsys_compat;
457 					break;
458 				}
459 			}
460 		}
461 		if (formats[i].delsys == 0) {
462 			sprintf(err_msg,
463 				 _("delivery system %d not supported on this format"),
464 				 delsys);
465 			goto error;
466 		}
467 		adjust_delsys(entry);
468 		if (parse_file->has_delsys_id) {
469 			fprintf(fp, "%s", formats[i].id);
470 			first = 0;
471 		} else
472 			first = 1;
473 
474 		fmt = &formats[i];
475 		for (i = 0; i < fmt->size; i++) {
476 			table = &fmt->table[i];
477 
478 			if (first)
479 				first = 0;
480 			else
481 				fprintf(fp, "%c", delimiter);
482 
483 			for (j = 0; j < entry->n_props; j++)
484 				if (entry->props[j].cmd == table->prop)
485 					break;
486 			if (fmt->table[i].has_default_value &&
487 			   (j < entry->n_props) &&
488 			   (fmt->table[i].default_value == entry->props[j].u.data))
489 				break;
490 			if (table->size && j < entry->n_props) {
491 				data = entry->props[j].u.data;
492 
493 				if (table->prop == DTV_BANDWIDTH_HZ) {
494 					for (j = 0; j < ARRAY_SIZE(fe_bandwidth_name); j++) {
495 						if (fe_bandwidth_name[j] == data) {
496 							data = j;
497 							break;
498 						}
499 					}
500 					if (j == ARRAY_SIZE(fe_bandwidth_name))
501 						data = BANDWIDTH_AUTO;
502 				}
503 				if (data >= table->size) {
504 					sprintf(err_msg,
505 						 _("value not supported"));
506 					goto error;
507 				}
508 
509 				fprintf(fp, "%s", table->table[data]);
510 			} else {
511 				switch (table->prop) {
512 				case DTV_VIDEO_PID:
513 					if (!entry->video_pid) {
514 						fprintf(stderr,
515 							_("WARNING: missing video PID while parsing entry %d of %s\n"),
516 							line, fname);
517 						fprintf(fp, "%d",0);
518 					} else
519 						fprintf(fp, "%d",
520 							entry->video_pid[0]);
521 					break;
522 				case DTV_AUDIO_PID:
523 					if (!entry->audio_pid) {
524 						fprintf(stderr,
525 							_("WARNING: missing audio PID while parsing entry %d of %s\n"),
526 							line, fname);
527 						fprintf(fp, "%d",0);
528 					} else
529 						fprintf(fp, "%d",
530 							entry->audio_pid[0]);
531 					break;
532 				case DTV_SERVICE_ID:
533 					fprintf(fp, "%d", entry->service_id);
534 					break;
535 				case DTV_CH_NAME:
536 					fprintf(fp, "%s", entry->channel);
537 					break;
538 				default:
539 					if (j >= entry->n_props) {
540 						if (fmt->table[i].has_default_value) {
541 							data = fmt->table[i].default_value;
542 						} else {
543 							fprintf(stderr,
544 								_("property %s not supported while parsing entry %d of %s\n"),
545 								dvb_cmd_name(table->prop),
546 								line, fname);
547 							data = 0;
548 						}
549 					} else {
550 						data = entry->props[j].u.data;
551 
552 					fprintf(fp, "%d", data);
553 				}
554 					break;
555 				}
556 			}
557 		}
558 		fprintf(fp, "\n");
559 		line++;
560 	};
561 	fclose (fp);
562 	return 0;
563 
564 error:
565 	fprintf(stderr, _("ERROR: %s while parsing entry %d of %s\n"),
566 		 err_msg, line, fname);
567 	fclose(fp);
568 	return -1;
569 }
570 
571 #define CHANNEL "CHANNEL"
572 
fill_entry(struct dvb_entry * entry,char * key,char * value)573 static int fill_entry(struct dvb_entry *entry, char *key, char *value)
574 {
575 	int i, j, len, type = 0;
576 	int is_video = 0, is_audio = 0, n_prop;
577 	uint16_t *pid = NULL;
578 	char *p;
579 
580 	/* Handle the DVBv5 DTV_foo properties */
581 	for (i = 0; i < ARRAY_SIZE(dvb_v5_name); i++) {
582 		if (!dvb_v5_name[i])
583 			continue;
584 		if (!strcasecmp(key, dvb_v5_name[i]))
585 			break;
586 	}
587 	if (i < ARRAY_SIZE(dvb_v5_name)) {
588 		const char * const *attr_name = dvb_attr_names(i);
589 		n_prop = entry->n_props;
590 		entry->props[n_prop].cmd = i;
591 		if (!attr_name || !*attr_name)
592 			entry->props[n_prop].u.data = atol(value);
593 		else {
594 			for (j = 0; attr_name[j]; j++)
595 				if (!strcasecmp(value, attr_name[j]))
596 					break;
597 			if (!attr_name[j])
598 				return -2;
599 			entry->props[n_prop].u.data = j;
600 		}
601 		entry->n_props++;
602 		return 0;
603 	}
604 
605 	/* Handle the other properties */
606 
607 	if (!strcasecmp(key, "SERVICE_ID")) {
608 		entry->service_id = atol(value);
609 		return 0;
610 	}
611 
612 	if (!strcasecmp(key, "NETWORK_ID")) {
613 		entry->network_id = atol(value);
614 		return 0;
615 	}
616 
617 	if (!strcasecmp(key, "TRANSPORT_ID")) {
618 		entry->transport_id = atol(value);
619 		return 0;
620 	}
621 
622 	if (!strcasecmp(key, "VCHANNEL")) {
623 		entry->vchannel = strdup(value);
624 		return 0;
625 	}
626 
627 	if (!strcasecmp(key, "SAT_NUMBER")) {
628 		entry->sat_number = atol(value);
629 		return 0;
630 	}
631 
632 	if (!strcasecmp(key, "FREQ_BPF")) {
633 		entry->freq_bpf = atol(value);
634 		return 0;
635 	}
636 
637 	if (!strcasecmp(key, "DISEQC_WAIT")) {
638 		entry->diseqc_wait = atol(value);
639 		return 0;
640 	}
641 
642 	if (!strcasecmp(key, "LNB")) {
643 		entry->lnb = strdup(value);
644 		return 0;
645 	}
646 
647 	if (!strcasecmp(key, "COUNTRY")) {
648 		enum dvb_country_t id = dvb_country_a2_to_id(value);
649 		if (id == COUNTRY_UNKNOWN)
650 			return -2;
651 		dvb_store_entry_prop(entry, DTV_COUNTRY_CODE, id);
652 		return 0;
653 	}
654 
655 	if (!strcasecmp(key, "VIDEO_PID"))
656 		is_video = 1;
657 	else if (!strcasecmp(key, "AUDIO_PID"))
658 		is_audio = 1;
659 	else if (!strcasecmp(key, "POLARIZATION")) {
660 		for (j = 0; j < ARRAY_SIZE(dvb_sat_pol_name); j++)
661 			if (dvb_sat_pol_name[j] && !strcasecmp(value, dvb_sat_pol_name[j]))
662 				break;
663 		if (j == ARRAY_SIZE(dvb_sat_pol_name))
664 			return -2;
665 		dvb_store_entry_prop(entry, DTV_POLARIZATION, j);
666 		return 0;
667 	} else if (!strncasecmp(key,"PID_", 4)){
668 		type = strtol(&key[4], NULL, 16);
669 		if (!type)
670 			return 0;
671 
672 		len = 0;
673 
674 		p = strtok(value," \t");
675 		if (!p)
676 			return 0;
677 		while (p) {
678 			entry->other_el_pid = realloc(entry->other_el_pid,
679 						      (len + 1) *
680 						      sizeof (*entry->other_el_pid));
681 			entry->other_el_pid[len].type = type;
682 			entry->other_el_pid[len].pid = atol(p);
683 			p = strtok(NULL, " \t\n");
684 			len++;
685 		}
686 		entry->other_el_pid_len = len;
687 	}
688 
689 	if (!is_video && !is_audio) {
690 		int cmd = 0;
691 
692 		for (i = 0; i < DTV_USER_NAME_SIZE; i++) {
693 			cmd = i + DTV_USER_COMMAND_START;
694 
695 			if (!strcasecmp(key, dvb_user_name[i]))
696 				break;
697 		}
698 
699 		/*
700 		 * If the key is not known, just discard.
701 		 * This way, it provides forward compatibility with new keys
702 		 * that may be added in the future.
703 		 */
704 
705 		if (i >= DTV_USER_NAME_SIZE)
706 			return 0;
707 
708 		/* FIXME: this works only for integer values */
709 		n_prop = entry->n_props;
710 		entry->props[n_prop].cmd = cmd;
711 		entry->props[n_prop].u.data = atol(value);
712 		entry->n_props++;
713 
714 		return 0;
715 	}
716 
717 	/* Video and audio may have multiple values */
718 
719 	len = 0;
720 
721 	p = strtok(value," \t");
722 	if (!p)
723 		return 0;
724 	while (p) {
725 		pid = realloc(pid, (len + 1) * sizeof (*pid));
726 		pid[len] = atol(p);
727 		p = strtok(NULL, " \t\n");
728 		len++;
729 	}
730 
731 	if (is_video) {
732 		entry->video_pid = pid;
733 		entry->video_pid_len = len;
734 	} else {
735 		entry->audio_pid = pid;
736 		entry->audio_pid_len = len;
737 	}
738 
739 	return 0;
740 }
741 
742 
dvb_read_file(const char * fname)743 struct dvb_file *dvb_read_file(const char *fname)
744 {
745 	char *buf = NULL, *p, *key, *value;
746 	size_t size = 0;
747 	int len = 0;
748 	int line = 0, rc;
749 	struct dvb_file *dvb_file;
750 	FILE *fd;
751 	struct dvb_entry *entry = NULL;
752 	char err_msg[80];
753 
754 	dvb_file = calloc(sizeof(*dvb_file), 1);
755 	if (!dvb_file) {
756 		perror(_("Allocating memory for dvb_file"));
757 		return NULL;
758 	}
759 
760 	fd = fopen(fname, "r");
761 	if (!fd) {
762 		perror(fname);
763 		free(dvb_file);
764 		return NULL;
765 	}
766 
767 	do {
768 		len = getline(&buf, &size, fd);
769 		if (len <= 0)
770 			break;
771 		line++;
772 		p = buf;
773 		while (*p == ' ' || *p == '\t')
774 			p++;
775 		if (*p == '\n' || *p == '#' || *p == '\a' || *p == '\0')
776 			continue;
777 
778 		if (*p == '[') {
779 			/* NEW Entry */
780 			if (!entry) {
781 				dvb_file->first_entry = calloc(sizeof(*entry), 1);
782 				entry = dvb_file->first_entry;
783 			} else {
784 				adjust_delsys(entry);
785 				entry->next = calloc(sizeof(*entry), 1);
786 				entry = entry->next;
787 			}
788 			entry->sat_number = -1;
789 			p++;
790 			p = strtok(p, "]");
791 			if (!p) {
792 				sprintf(err_msg, _("Missing channel group"));
793 				goto error;
794 			}
795 			if (!strcasecmp(p, CHANNEL))
796 				p += strlen(CHANNEL);
797 			while (*p == ' ' || *p == '\t')
798 				p++;
799 			if (*p) {
800 				entry->channel = calloc(strlen(p) + 1, 1);
801 				strcpy(entry->channel, p);
802 			}
803 		} else {
804 			if (!entry) {
805 				sprintf(err_msg, _("key/value without a channel group"));
806 				goto error;
807 			}
808 			key = strtok(p, "=");
809 			if (!key) {
810 				sprintf(err_msg, _("missing key"));
811 				goto error;
812 			}
813 			p = &key[strlen(key) - 1];
814 			while ((p > key) && (*(p - 1) == ' ' || *(p - 1) == '\t'))
815 				p--;
816 			*p = 0;
817 			value = strtok(NULL, "\n");
818 			if (!value) {
819 				sprintf(err_msg, _("missing value"));
820 				goto error;
821 			}
822 			while (*value == ' ' || *value == '\t')
823 				value++;
824 
825 			rc = fill_entry(entry, key, value);
826 			if (rc == -2) {
827 				sprintf(err_msg, _("value %s is invalid for %s"),
828 					value, key);
829 				goto error;
830 			}
831 		}
832 	} while (1);
833 	if (buf)
834 		free(buf);
835 	if (entry)
836 		adjust_delsys(entry);
837 	fclose(fd);
838 	return dvb_file;
839 
840 error:
841 	fprintf (stderr, _("ERROR %s while parsing line %d of %s\n"),
842 		 err_msg, line, fname);
843 	if (buf)
844 		free(buf);
845 	dvb_file_free(dvb_file);
846 	fclose(fd);
847 	return NULL;
848 };
849 
dvb_write_file(const char * fname,struct dvb_file * dvb_file)850 int dvb_write_file(const char *fname, struct dvb_file *dvb_file)
851 {
852 	FILE *fp;
853 	int i;
854 	struct dvb_entry *entry = dvb_file->first_entry;
855 	static const char *off = "OFF";
856 
857 	fp = fopen(fname, "w");
858 	if (!fp) {
859 		perror(fname);
860 		return -errno;
861 	}
862 
863 	for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
864 		adjust_delsys(entry);
865 		if (entry->channel) {
866 			fprintf(fp, "[%s]\n", entry->channel);
867 			if (entry->vchannel)
868 				fprintf(fp, "\tVCHANNEL = %s\n", entry->vchannel);
869 		} else {
870 			fprintf(fp, "[CHANNEL]\n");
871 		}
872 
873 		if (entry->service_id)
874 			fprintf(fp, "\tSERVICE_ID = %d\n", entry->service_id);
875 
876 		if (entry->network_id)
877 			fprintf(fp, "\tNETWORK_ID = %d\n", entry->network_id);
878 
879 		if (entry->transport_id)
880 			fprintf(fp, "\tTRANSPORT_ID = %d\n", entry->transport_id);
881 
882 		if (entry->video_pid_len){
883 			fprintf(fp, "\tVIDEO_PID =");
884 			for (i = 0; i < entry->video_pid_len; i++)
885 				fprintf(fp, " %d", entry->video_pid[i]);
886 			fprintf(fp, "\n");
887 		}
888 
889 		if (entry->audio_pid_len) {
890 			fprintf(fp, "\tAUDIO_PID =");
891 			for (i = 0; i < entry->audio_pid_len; i++)
892 				fprintf(fp, " %d", entry->audio_pid[i]);
893 			fprintf(fp, "\n");
894 		}
895 
896 		if (entry->other_el_pid_len) {
897 			int type = -1;
898 			for (i = 0; i < entry->other_el_pid_len; i++) {
899 				if (type != entry->other_el_pid[i].type) {
900 					type = entry->other_el_pid[i].type;
901 					if (i)
902 						fprintf(fp, "\n");
903 					fprintf(fp, "\tPID_%02x =", type);
904 				}
905 				fprintf(fp, " %d", entry->other_el_pid[i].pid);
906 			}
907 			fprintf(fp, "\n");
908 		}
909 
910 		if (entry->sat_number >= 0) {
911 			fprintf(fp, "\tSAT_NUMBER = %d\n",
912 				entry->sat_number);
913 		}
914 
915 		if (entry->freq_bpf > 0) {
916 			fprintf(fp, "\tFREQ_BPF = %d\n",
917 				entry->freq_bpf);
918 		}
919 
920 		if (entry->diseqc_wait > 0) {
921 			fprintf(fp, "\tDISEQC_WAIT = %d\n",
922 				entry->diseqc_wait);
923 		}
924 		if (entry->lnb)
925 				fprintf(fp, "\tLNB = %s\n", entry->lnb);
926 
927 		for (i = 0; i < entry->n_props; i++) {
928 			const char * const *attr_name = dvb_attr_names(entry->props[i].cmd);
929 			const char *buf;
930 
931 			if (attr_name) {
932 				int j;
933 
934 				for (j = 0; j < entry->props[i].u.data; j++) {
935 					if (!*attr_name)
936 						break;
937 					attr_name++;
938 				}
939 			}
940 
941 			if (entry->props[i].cmd == DTV_COUNTRY_CODE) {
942 				buf = dvb_country_to_2letters(entry->props[i].u.data);
943 				attr_name = &buf;
944 			}
945 
946 			switch (entry->props[i].cmd) {
947 			/* Handle parameters with optional values */
948 			case DTV_PLS_CODE:
949 			case DTV_PLS_MODE:
950 				if (entry->props[i].u.data == (unsigned)-1)
951 					continue;
952 				break;
953 			case DTV_PILOT:
954 				if (entry->props[i].u.data == (unsigned)-1)
955 					attr_name = &off;
956 				break;
957 			}
958 
959 			if (!attr_name || !*attr_name)
960 				fprintf(fp, "\t%s = %u\n",
961 					dvb_cmd_name(entry->props[i].cmd),
962 					entry->props[i].u.data);
963 			else
964 				fprintf(fp, "\t%s = %s\n",
965 					dvb_cmd_name(entry->props[i].cmd),
966 					*attr_name);
967 		}
968 		fprintf(fp, "\n");
969 	}
970 	fclose(fp);
971 	return 0;
972 };
973 
dvb_vchannel(struct dvb_v5_fe_parms_priv * parms,struct dvb_table_nit * nit,uint16_t service_id)974 static char *dvb_vchannel(struct dvb_v5_fe_parms_priv *parms,
975 			  struct dvb_table_nit *nit, uint16_t service_id)
976 {
977 	int i;
978 	char *buf;
979 
980 	if (!nit)
981 		return NULL;
982 
983 	for( struct dvb_desc_logical_channel *desc = (struct dvb_desc_logical_channel *) nit->descriptor; desc; desc = (struct dvb_desc_logical_channel *) desc->next ) \
984 		if(desc->type == logical_channel_number_descriptor) {
985 /* FIXME:  dvb_desc_find(struct dvb_desc_logical_channel, desc, nit, logical_channel_number_descriptor) ? */
986 		struct dvb_desc_logical_channel *d = (void *)desc;
987 		size_t len;
988 		int r;
989 
990 		len = d->length / 4;
991 		for (i = 0; i < len; i++) {
992 			if (service_id == d->lcn[i].service_id) {
993 				r = asprintf(&buf, "%d.%d",
994 					d->lcn[i].logical_channel_number, i);
995 				if (r < 0)
996 					dvb_perror("asprintf");
997 				return buf;
998 			}
999 		}
1000 	}
1001 
1002 	dvb_desc_find(struct dvb_desc_ts_info, desc, nit, TS_Information_descriptior) {
1003 		const struct dvb_desc_ts_info *d = (const void *) desc;
1004 		const struct dvb_desc_ts_info_transmission_type *t;
1005 		int r;
1006 
1007 		t = &d->transmission_type;
1008 
1009 		for (i = 0; i < t->num_of_service; i++) {
1010 			if (d->service_id[i] == service_id) {
1011 				r = asprintf(&buf, "%d.%d",
1012 					d->remote_control_key_id, i);
1013 				if (r < 0)
1014 					dvb_perror("asprintf");
1015 				return buf;
1016 			}
1017 		}
1018 	}
1019 
1020 	return NULL;
1021 }
1022 
sort_other_el_pid(const void * a_arg,const void * b_arg)1023 static int sort_other_el_pid(const void *a_arg, const void *b_arg)
1024 {
1025 	const struct dvb_elementary_pid *a = a_arg, *b = b_arg;
1026 	int r;
1027 
1028 	r = b->type - a->type;
1029 	if (r)
1030 		return r;
1031 
1032 	return b->pid - a->pid;
1033 }
1034 
1035 
get_pmt_descriptors(struct dvb_entry * entry,struct dvb_table_pmt * pmt)1036 static void get_pmt_descriptors(struct dvb_entry *entry,
1037 				struct dvb_table_pmt *pmt)
1038 {
1039 	int has_ac3 = 0;
1040 	int video_len = 0, audio_len = 0, other_len = 0;
1041 
1042 	dvb_pmt_stream_foreach(stream, pmt) {
1043 		uint16_t  pid = stream->elementary_pid;
1044 
1045 		switch(stream->type) {
1046 		case 0x01: /* ISO/IEC 11172-2 Video */
1047 		case 0x02: /* H.262, ISO/IEC 13818-2 or ISO/IEC 11172-2 video */
1048 		case 0x1b: /* H.264 AVC */
1049 		case 0x24: /* HEVC */
1050 		case 0x42: /* CAVS */
1051 		case 0x80: /* MPEG-2 MOTO video */
1052 			entry->video_pid = realloc(entry->video_pid,
1053 						   sizeof(*entry->video_pid) *
1054 						   (video_len + 1));
1055 			entry->video_pid[video_len] = pid;
1056 			video_len++;
1057 			break;
1058 		case 0x03: /* ISO/IEC 11172-3 Audio */
1059 		case 0x04: /* ISO/IEC 13818-3 Audio */
1060 		case 0x07: /* DTS and DTS-HD Audio */
1061 		case 0x0f: /* ISO/IEC 13818-7 Audio with ADTS (AAC) */
1062 		case 0x11: /* ISO/IEC 14496-3 Audio with the LATM */
1063 		case 0x1c: /* ISO/IEC 14496-3 Audio, without additional transport syntax */
1064 		case 0x81: /* A52 */
1065 		case 0x84: /* SDDS */
1066 		case 0x85: /* DTS on HDMV */
1067 		case 0x87: /* E-AC3 */
1068 		case 0x8a: /* DTS */
1069 		case 0x91: /* A52 VLS */
1070 		case 0x94: /* SDDS */
1071 			entry->audio_pid = realloc(entry->audio_pid,
1072 						   sizeof(*entry->audio_pid) *
1073 						   (audio_len + 1));
1074 			entry->audio_pid[audio_len] = pid;
1075 			audio_len++;
1076 			break;
1077 		case 0x05: /* private sections */
1078 		case 0x06: /* private data */
1079 			/*
1080 			* Those can be used by sub-titling, teletext and/or
1081 			* DVB AC-3. So, need to seek for the AC-3 descriptors
1082 			*/
1083 			dvb_desc_find(struct dvb_desc_service, desc, stream, AC_3_descriptor)
1084 				has_ac3 = 1;
1085 
1086 			dvb_desc_find(struct dvb_desc_service, desc, stream, enhanced_AC_3_descriptor)
1087 				has_ac3 = 1;
1088 
1089 			if (has_ac3) {
1090 				entry->audio_pid = realloc(entry->audio_pid,
1091 							   sizeof(*entry->audio_pid) *
1092 							   (audio_len + 1));
1093 				entry->audio_pid[audio_len] = pid;
1094 				audio_len++;
1095 			} else {
1096 				entry->other_el_pid = realloc(entry->other_el_pid,
1097 							   sizeof(*entry->other_el_pid) *
1098 							   (other_len + 1));
1099 				entry->other_el_pid[other_len].type = stream->type;
1100 				entry->other_el_pid[other_len].pid = pid;
1101 				other_len++;
1102 			}
1103 			break;
1104 		default:
1105 			entry->other_el_pid = realloc(entry->other_el_pid,
1106 						   sizeof(*entry->other_el_pid) *
1107 						   (other_len + 1));
1108 			entry->other_el_pid[other_len].type = stream->type;
1109 			entry->other_el_pid[other_len].pid = pid;
1110 			other_len++;
1111 			break;
1112 		}
1113 	}
1114 
1115 	entry->video_pid_len = video_len;
1116 	entry->audio_pid_len = audio_len;
1117 	entry->other_el_pid_len = other_len;
1118 
1119 	qsort(entry->other_el_pid, entry->other_el_pid_len,
1120 	      sizeof(*entry->other_el_pid), sort_other_el_pid);
1121 }
1122 
get_program_and_store(struct dvb_v5_fe_parms_priv * parms,struct dvb_file * dvb_file,struct dvb_v5_descriptors * dvb_scan_handler,const uint16_t service_id,const uint16_t network_id,const uint16_t transport_id,char * channel,char * vchannel,int get_detected,int get_nit)1123 static int get_program_and_store(struct dvb_v5_fe_parms_priv *parms,
1124 				 struct dvb_file *dvb_file,
1125 				 struct dvb_v5_descriptors *dvb_scan_handler,
1126 				 const uint16_t service_id,
1127 				 const uint16_t network_id,
1128 				 const uint16_t transport_id,
1129 				 char *channel,
1130 				 char *vchannel,
1131 				 int get_detected, int get_nit)
1132 {
1133 	struct dvb_entry *entry;
1134 	int i, j, r, found = 0;
1135 	uint32_t freq = 0;
1136 
1137 	/* Go to the last entry */
1138 
1139 	if (dvb_file->first_entry) {
1140 		entry = dvb_file->first_entry;
1141 		while (entry && entry->next)
1142 			entry = entry->next;
1143 	}
1144 
1145 	for (i = 0; i < dvb_scan_handler->num_program; i++) {
1146 		if (!dvb_scan_handler->program[i].pmt)
1147 			continue;
1148 
1149 		if (service_id == dvb_scan_handler->program[i].pat_pgm->service_id) {
1150 			found = 1;
1151 			break;
1152 		}
1153 	}
1154 	if (!found) {
1155 		dvb_logwarn(_("Channel %s (service ID %d) not found on PMT. Skipping it."),
1156 			    channel, service_id);
1157 		if (channel)
1158 			free(channel);
1159 		if (vchannel)
1160 			free(vchannel);
1161 		return 0;
1162 	}
1163 
1164 	/* Create an entry to store the data */
1165 	if (!dvb_file->first_entry) {
1166 		dvb_file->first_entry = calloc(sizeof(*entry), 1);
1167 		entry = dvb_file->first_entry;
1168 	} else {
1169 		entry->next = calloc(sizeof(*entry), 1);
1170 		entry = entry->next;
1171 	}
1172 	if (!entry) {
1173 		dvb_logerr(_("Not enough memory"));
1174 		if (channel)
1175 			free(channel);
1176 		if (vchannel)
1177 			free(vchannel);
1178 		return -1;
1179 	}
1180 
1181 	/* Initialize data */
1182 	entry->service_id = service_id;
1183 	entry->network_id = network_id;
1184 	entry->transport_id = transport_id;
1185 	entry->vchannel = vchannel;
1186 	entry->sat_number = parms->p.sat_number;
1187 	entry->freq_bpf = parms->p.freq_bpf;
1188 	entry->diseqc_wait = parms->p.diseqc_wait;
1189 	if (parms->p.lnb)
1190 		entry->lnb = strdup(parms->p.lnb->alias);
1191 
1192 	/* Get PIDs for each elementary inside the service ID */
1193 	get_pmt_descriptors(entry, dvb_scan_handler->program[i].pmt);
1194 
1195 	/* Copy data from parms */
1196 	if (get_detected) {
1197 		int rc;
1198 		do {
1199 			rc = dvb_fe_get_parms(&parms->p);
1200 			if (rc == EAGAIN)
1201 				usleep(100000);
1202 		} while (rc == EAGAIN);
1203 		if (rc)
1204 			dvb_logerr(_("Couldn't get frontend props"));
1205 	}
1206 	for (j = 0; j < parms->n_props; j++) {
1207 		entry->props[j].cmd = parms->dvb_prop[j].cmd;
1208 		entry->props[j].u.data = parms->dvb_prop[j].u.data;
1209 
1210 		/* [ISDB-S]
1211 		 * Update DTV_STREAM_ID if it was not specified by a user
1212 		 * or set to a wrong one.
1213 		 * In those cases, demod must have selected the first TS_ID.
1214 		 * The update must be after the above dvb_fe_get_parms() call,
1215 		 * since a lazy FE driver that does not update stream_id prop
1216 		 * cache in FE.get_frontend() may overwrite the setting again
1217 		 * with the initial / user-specified wrong value.
1218 		 */
1219 		if (entry->props[j].cmd == DTV_STREAM_ID
1220 		    && entry->props[j].u.data == 0
1221 		    && parms->p.current_sys == SYS_ISDBS)
1222 			entry->props[j].u.data = dvb_scan_handler->pat->header.id;
1223 
1224 		if (!channel && entry->props[j].cmd == DTV_FREQUENCY)
1225 			freq = parms->dvb_prop[j].u.data;
1226 	}
1227 	if (!channel) {
1228 		r = asprintf(&channel, "%.2f%cHz#%d", freq / 1000000.,
1229 			dvb_fe_is_satellite(parms->p.current_sys) ? 'G' : 'M',
1230 			service_id);
1231 		if (r < 0)
1232 			dvb_perror("asprintf");
1233 		dvb_log(_("Storing Service ID %d: '%s'"), service_id, channel);
1234 	}
1235 	entry->n_props = parms->n_props;
1236 	entry->channel = channel;
1237 
1238 	if (get_nit)
1239 		dvb_update_transponders(&parms->p, dvb_scan_handler,
1240 					dvb_file->first_entry,
1241 					entry);
1242 
1243 	return 0;
1244 }
1245 
1246 /* Service type, according with EN 300 468 V1.3.1 (1998-02) */
1247 static char *sdt_services[256] = {
1248 	[0x00 ...0xff] = N_("reserved"),
1249 	[0x01] = N_("digital television"),
1250 	[0x02] = N_("digital radio"),
1251 	[0x03] = N_("Teletext"),
1252 	[0x04] = N_("NVOD reference"),
1253 	[0x05] = N_("NVOD time-shifted"),
1254 	[0x06] = N_("mosaic"),
1255 	[0x07] = N_("PAL coded signal"),
1256 	[0x08] = N_("SECAM coded signal"),
1257 	[0x09] = N_("D/D2-MAC"),
1258 	[0x0a] = N_("FM Radio"),
1259 	[0x0b] = N_("NTSC coded signal"),
1260 	[0x0c] = N_("data broadcast"),
1261 	[0x80 ...0xfe] = N_("user defined"),
1262 };
1263 
dvb_store_channel(struct dvb_file ** dvb_file,struct dvb_v5_fe_parms * __p,struct dvb_v5_descriptors * dvb_scan_handler,int get_detected,int get_nit)1264 int dvb_store_channel(struct dvb_file **dvb_file,
1265 		      struct dvb_v5_fe_parms *__p,
1266 		      struct dvb_v5_descriptors *dvb_scan_handler,
1267 		      int get_detected, int get_nit)
1268 {
1269 	struct dvb_v5_fe_parms_priv *parms = (void *)__p;
1270 	int rc;
1271 	int num_services = 0;
1272 
1273 	if (!*dvb_file) {
1274 		*dvb_file = calloc(sizeof(**dvb_file), 1);
1275 		if (!*dvb_file) {
1276 			dvb_perror(_("Allocating memory for dvb_file"));
1277 			return -1;
1278 		}
1279 	}
1280 
1281 	if (dvb_scan_handler->vct) {
1282 		atsc_vct_channel_foreach(d, dvb_scan_handler->vct) {
1283 			char *channel = NULL;
1284 			char *vchannel = NULL;
1285 			char *p = d->short_name;
1286 			int r;
1287 
1288 			while (*p == ' ')
1289 				p++;
1290 			channel = calloc(1, strlen(p) + 1);
1291 			strcpy(channel, p);
1292 
1293 			r = asprintf(&vchannel, "%d.%d",
1294 				d->major_channel_number,
1295 				d->minor_channel_number);
1296 			if (r < 0)
1297 				dvb_perror("asprintf");
1298 
1299 			if (parms->p.verbose)
1300 				dvb_log(_("Virtual channel %s, name = %s"),
1301 					vchannel, channel);
1302 
1303 			rc = get_program_and_store(parms, *dvb_file, dvb_scan_handler,
1304 						d->program_number, 0, 0,
1305 						channel, vchannel,
1306 						get_detected, get_nit);
1307 			if (rc < 0)
1308 				return rc;
1309 		}
1310 		if (!dvb_scan_handler->sdt)
1311 			return 0;
1312 	}
1313 
1314 	dvb_sdt_service_foreach(service, dvb_scan_handler->sdt) {
1315 		char *channel = NULL;
1316 		char *vchannel = NULL;
1317 		uint16_t network_id = 0, transport_id = 0;
1318 		int r;
1319 
1320 		dvb_desc_find(struct dvb_desc_service, desc, service, service_descriptor) {
1321 			if (desc->name) {
1322 				char *p = desc->name;
1323 
1324 				while (*p == ' ')
1325 					p++;
1326 				channel = calloc(strlen(p) + 1, 1);
1327 				strcpy(channel, p);
1328 			}
1329 			dvb_log(_("Service %s, provider %s: %s"),
1330 				desc->name, desc->provider,
1331 				_(sdt_services[desc->service_type]));
1332 			break;
1333 		}
1334 
1335 		if (!channel) {
1336 			r = asprintf(&channel, "#%d", service->service_id);
1337 			if (r < 0)
1338 				dvb_perror("asprintf");
1339 		}
1340 
1341 		if (parms->p.verbose)
1342 			dvb_log(_("Storing as channel %s"), channel);
1343 		vchannel = dvb_vchannel(parms, dvb_scan_handler->nit, service->service_id);
1344 
1345 		if (dvb_scan_handler->nit && dvb_scan_handler->nit->transport) {
1346 			network_id = dvb_scan_handler->nit->transport->network_id;
1347 			transport_id = dvb_scan_handler->nit->transport->transport_id;
1348 		}
1349 
1350 		rc = get_program_and_store(parms, *dvb_file, dvb_scan_handler,
1351 					   service->service_id,
1352 					   network_id,
1353 					   transport_id,
1354 					   channel, vchannel,
1355 					   get_detected, get_nit);
1356 		if (rc < 0)
1357 			return rc;
1358 
1359 		num_services++;
1360 	}
1361 
1362 	if (!dvb_scan_handler->sdt || num_services < dvb_scan_handler->num_program) {
1363 		int warned = 0;
1364 		int i;
1365 
1366 		for (i = 0; i < dvb_scan_handler->num_program; i++) {
1367 			int found = 0;
1368 			unsigned service_id;
1369 
1370 			if (!dvb_scan_handler->program[i].pmt)
1371 				continue;
1372 
1373 			service_id = dvb_scan_handler->program[i].pat_pgm->service_id;
1374 			dvb_sdt_service_foreach(service, dvb_scan_handler->sdt) {
1375 				if (service->service_id == service_id) {
1376 					found = 1;
1377 					break;
1378 				}
1379 			}
1380 			if (found)
1381 				continue;
1382 
1383 			if (!warned) {
1384 				if (!dvb_scan_handler->sdt)
1385 					dvb_log(_("WARNING: no SDT table - storing channel(s) without their names"));
1386 				else
1387 					dvb_log(_("WARNING: Some Service IDs are not at the SDT table"));
1388 				warned = 1;
1389 			}
1390 
1391 			rc = get_program_and_store(parms, *dvb_file, dvb_scan_handler,
1392 						   service_id, 0, 0,
1393 						   NULL, NULL,
1394 						   get_detected, get_nit);
1395 			if (rc < 0)
1396 				return rc;
1397 		}
1398 
1399 		return 0;
1400 	}
1401 
1402 	return 0;
1403 }
1404 
dvb_parse_format(const char * name)1405 enum dvb_file_formats dvb_parse_format(const char *name)
1406 {
1407 	if (!strcasecmp(name, "ZAP"))
1408 		return FILE_ZAP;
1409 	if (!strcasecmp(name, "CHANNEL"))
1410 		return FILE_CHANNEL;
1411 	if (!strcasecmp(name, "DVBV5"))
1412 		return FILE_DVBV5;
1413 	if (!strcasecmp(name, "VDR"))
1414 		return FILE_VDR;
1415 
1416 	fprintf(stderr, _("File format %s is unknown\n"), name);
1417 	return FILE_UNKNOWN;
1418 }
1419 
1420 static struct {
1421 	uint32_t delsys;
1422 	char *name;
1423 } alt_names[] = {
1424 	{ SYS_DVBC_ANNEX_A,	"DVB-C" },
1425 	{ SYS_DVBH,		"DVB-H" },
1426 	{ SYS_DVBS,		"DVB-S" },
1427 	{ SYS_DVBS2,		"DVB-S2" },
1428 	{ SYS_DVBT,		"DVB-T" },
1429 	{ SYS_DVBT2,		"DVB-T2" },
1430 	{ SYS_ISDBC,		"ISDB-C" },
1431 	{ SYS_ISDBS,		"ISDB-S" },
1432 	{ SYS_ISDBT,		"ISDB-T" },
1433 	{ SYS_ATSCMH,		"ATSC-MH" },
1434 	{ SYS_DTMB,		"DMB-TH" },
1435 	{ SYS_DTMB,		"DMB" },
1436 };
1437 
dvb_parse_delsys(const char * name)1438 int dvb_parse_delsys(const char *name)
1439 {
1440 	int i, cnt = 0;
1441 
1442 	/* Check for DVBv5 names */
1443 	for (i = 0; i < ARRAY_SIZE(delivery_system_name); i++)
1444 		if (delivery_system_name[i] &&
1445 			!strcasecmp(name, delivery_system_name[i]))
1446 			break;
1447 	if (i < ARRAY_SIZE(delivery_system_name))
1448 		return i;
1449 
1450 	/* Also accept the alternative names */
1451 	for (i = 0; i < ARRAY_SIZE(alt_names); i++)
1452 		if (!strcasecmp(name, alt_names[i].name))
1453 			break;
1454 	if (i < ARRAY_SIZE(alt_names))
1455 		return alt_names[i].delsys;
1456 
1457 	/*
1458 	 * Not found. Print all possible values, except for
1459 	 * SYS_UNDEFINED.
1460 	 */
1461 	fprintf(stderr, _("ERROR: Delivery system %s is not known. Valid values are:\n"),
1462 		name);
1463 	for (i = 0; i < ARRAY_SIZE(alt_names) - 1; i++) {
1464 		if (!(cnt % 5))
1465 			fprintf(stderr, "\n");
1466 		fprintf(stderr, "%-15s", alt_names[i].name);
1467 		cnt++;
1468 	}
1469 
1470 	for (i = 1; i < ARRAY_SIZE(delivery_system_name) - 1; i++) {
1471 		if (!(cnt % 5))
1472 			fprintf(stderr, "\n");
1473 		fprintf(stderr, "%-15s", delivery_system_name[i]);
1474 		cnt++;
1475 	}
1476 	if (cnt % 5)
1477 		fprintf(stderr, "\n");
1478 
1479 	fprintf(stderr, "\n");
1480 	return -1;
1481 }
1482 
dvb_read_file_format(const char * fname,uint32_t delsys,enum dvb_file_formats format)1483 struct dvb_file *dvb_read_file_format(const char *fname,
1484 				  uint32_t delsys,
1485 				  enum dvb_file_formats format)
1486 {
1487 	struct dvb_file *dvb_file;
1488 
1489 	switch (format) {
1490 	case FILE_CHANNEL:		/* DVB channel/transponder old format */
1491 		dvb_file = dvb_parse_format_oneline(fname,
1492 						    SYS_UNDEFINED,
1493 						    &channel_file_format);
1494 		break;
1495 	case FILE_ZAP:
1496 		dvb_file = dvb_parse_format_oneline(fname,
1497 						    delsys,
1498 						    &channel_file_zap_format);
1499 		break;
1500 	case FILE_DVBV5:
1501 		dvb_file = dvb_read_file(fname);
1502 		break;
1503 	case FILE_VDR:
1504 		/* FIXME: add support for VDR input */
1505 		fprintf(stderr, _("Currently, VDR format is supported only for output\n"));
1506 		return NULL;
1507 	default:
1508 		fprintf(stderr, _("Format is not supported\n"));
1509 		return NULL;
1510 	}
1511 
1512 	return dvb_file;
1513 }
1514 
dvb_write_file_format(const char * fname,struct dvb_file * dvb_file,uint32_t delsys,enum dvb_file_formats format)1515 int dvb_write_file_format(const char *fname,
1516 			  struct dvb_file *dvb_file,
1517 			  uint32_t delsys,
1518 			  enum dvb_file_formats format)
1519 {
1520 	int ret;
1521 
1522 	switch (format) {
1523 	case FILE_CHANNEL:		/* DVB channel/transponder old format */
1524 		ret = dvb_write_format_oneline(fname,
1525 					       dvb_file,
1526 					       SYS_UNDEFINED,
1527 					       &channel_file_format);
1528 		break;
1529 	case FILE_ZAP:
1530 		ret = dvb_write_format_oneline(fname,
1531 					       dvb_file,
1532 					       delsys,
1533 					       &channel_file_zap_format);
1534 		break;
1535 	case FILE_DVBV5:
1536 		ret = dvb_write_file(fname, dvb_file);
1537 		break;
1538 	case FILE_VDR:
1539 		ret = dvb_write_format_vdr(fname, dvb_file);
1540 		break;
1541 	default:
1542 		return -1;
1543 	}
1544 
1545 	return ret;
1546 }
1547