diff options
| author | etobi <git@e-tobi.net> | 2013-09-03 09:48:41 +0200 | 
|---|---|---|
| committer | etobi <git@e-tobi.net> | 2013-09-03 09:48:41 +0200 | 
| commit | ab959d7b4194715870128e616b8e29d4a101e488 (patch) | |
| tree | 61a746231d30817be73416a7d67763fd677a1042 /lib/libdvbcfg | |
| parent | 6b350466c4902c5b137e0efaf1d189128a7f18f5 (diff) | |
| download | linux-dvb-apps-ab959d7b4194715870128e616b8e29d4a101e488.tar.gz | |
Imported Upstream version 1.1.1+rev1207upstream/1.1.1+rev1207
Diffstat (limited to 'lib/libdvbcfg')
| -rw-r--r-- | lib/libdvbcfg/Makefile | 18 | ||||
| -rw-r--r-- | lib/libdvbcfg/dvbcfg_common.c | 136 | ||||
| -rw-r--r-- | lib/libdvbcfg/dvbcfg_common.h | 37 | ||||
| -rw-r--r-- | lib/libdvbcfg/dvbcfg_scanfile.c | 282 | ||||
| -rw-r--r-- | lib/libdvbcfg/dvbcfg_scanfile.h | 61 | ||||
| -rw-r--r-- | lib/libdvbcfg/dvbcfg_zapchannel.c | 384 | ||||
| -rw-r--r-- | lib/libdvbcfg/dvbcfg_zapchannel.h | 77 | ||||
| -rw-r--r-- | lib/libdvbcfg/zapchannel.txt | 72 | 
8 files changed, 1067 insertions, 0 deletions
| diff --git a/lib/libdvbcfg/Makefile b/lib/libdvbcfg/Makefile new file mode 100644 index 0000000..5e5e365 --- /dev/null +++ b/lib/libdvbcfg/Makefile @@ -0,0 +1,18 @@ +# Makefile for linuxtv.org dvb-apps/lib/libdvbcfg + +includes = dvbcfg_zapchannel.h \ +	   dvbcfg_scanfile.h + +objects  = dvbcfg_zapchannel.o \ +	   dvbcfg_scanfile.o \ +	   dvbcfg_common.o + +lib_name = libdvbcfg + +CPPFLAGS += -I../../lib + +.PHONY: all + +all: library + +include ../../Make.rules diff --git a/lib/libdvbcfg/dvbcfg_common.c b/lib/libdvbcfg/dvbcfg_common.c new file mode 100644 index 0000000..1609e51 --- /dev/null +++ b/lib/libdvbcfg/dvbcfg_common.c @@ -0,0 +1,136 @@ +/* + * dvbcfg - support for linuxtv configuration files + * common functions + * + * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com> + * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdio.h> +#include <string.h> +#include <ctype.h> +#include "dvbcfg_common.h" + +int dvbcfg_parse_int(char **text, char *tokens) +{ +	char *start = *text; +	char *stop = *text; +	int value; + +	while (*stop != '\0') { +		if (strchr(tokens, *stop) != NULL) { +			*stop = '\0'; +			stop++; +			break; +		} +		stop++; +	} + +	if (sscanf(start, "%i", &value) == 1) { +		*text = stop; +		return value; +	} + +	*text = NULL; +	return -1; +} + +int dvbcfg_parse_char(char **text, char *tokens) +{ +	char *start = *text; +	char *stop = *text; +	char value; + +	while (*stop != '\0') { +		if (strchr(tokens, *stop) != NULL) { +			*stop = '\0'; +			stop++; +			break; +		} +		stop++; +	} + +	if (sscanf(start, "%c", &value) == 1) { +		*text = stop; +		return value; +	} + +	*text = NULL; +	return -1; +} + +int dvbcfg_parse_setting(char **text, char *tokens, const struct dvbcfg_setting *settings) +{ +	char *start = *text; +	char *stop = *text; + +	while (*stop != '\0') { +		if (strchr(tokens, *stop) != NULL) { +			*stop = '\0'; +			stop++; +			break; +		} +		stop++; +	} + +	while (settings->name) { +		if (strcmp(start, settings->name) == 0) { +			*text = stop; +			return settings->value; +		} +		settings++; +	} + +	*text = NULL; +	return -1; +} + +void dvbcfg_parse_string(char **text, char *tokens, char *dest, unsigned long size) +{ +	char *start = *text; +	char *stop = *text; +	unsigned long length; + +	while ((*stop != '\0') && (strchr(tokens, *stop) == NULL)) +		stop++; + +	length = (stop - start) + 1; + +	if (length <= size) { +		if (strchr(tokens, *stop) != NULL) { +			*stop = '\0'; +			*text = stop + 1; +		} else +			*text = stop; +			memcpy(dest, start, length); +			return; +	} + +	*text = NULL; +	return; +} + +const char *dvbcfg_lookup_setting(unsigned int setting, const struct dvbcfg_setting *settings) +{ +	while (settings->name) { +		if (setting == settings->value) +			return settings->name; +		settings++; +	} + +	return NULL; +} diff --git a/lib/libdvbcfg/dvbcfg_common.h b/lib/libdvbcfg/dvbcfg_common.h new file mode 100644 index 0000000..2b5e876 --- /dev/null +++ b/lib/libdvbcfg/dvbcfg_common.h @@ -0,0 +1,37 @@ +/* + * dvbcfg - support for linuxtv configuration files + * common functions + * + * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com> + * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DVBCFG_COMMON_H +#define DVBCFG_COMMON_H 1 + +struct dvbcfg_setting { +	const char *name; +	unsigned int value; +}; + +extern int dvbcfg_parse_int(char **text, char *tokens); +extern int dvbcfg_parse_char(char **text, char *tokens); +extern int dvbcfg_parse_setting(char **text, char *tokens, const struct dvbcfg_setting *settings); +extern void dvbcfg_parse_string(char **text, char *tokens, char *dest, unsigned long size); +extern const char *dvbcfg_lookup_setting(unsigned int setting, const struct dvbcfg_setting *settings); + +#endif diff --git a/lib/libdvbcfg/dvbcfg_scanfile.c b/lib/libdvbcfg/dvbcfg_scanfile.c new file mode 100644 index 0000000..ec305a4 --- /dev/null +++ b/lib/libdvbcfg/dvbcfg_scanfile.c @@ -0,0 +1,282 @@ +/* + * dvbcfg - support for linuxtv configuration files + * scan channel file support + * + * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com> + * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define _GNU_SOURCE + +#include <malloc.h> +#include <ctype.h> + +#include "dvbcfg_scanfile.h" +#include "dvbcfg_common.h" + +static const struct dvbcfg_setting dvbcfg_fec_list[] = { +	{ "1/2",  DVBFE_FEC_1_2  }, +	{ "2/3",  DVBFE_FEC_2_3  }, +	{ "3/4",  DVBFE_FEC_3_4  }, +	{ "4/5",  DVBFE_FEC_4_5  }, +	{ "5/6",  DVBFE_FEC_5_6  }, +	{ "6/7",  DVBFE_FEC_6_7  }, +	{ "7/8",  DVBFE_FEC_7_8  }, +	{ "8/9",  DVBFE_FEC_8_9  }, +	{ "AUTO", DVBFE_FEC_AUTO }, +	{ "NONE", DVBFE_FEC_NONE }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_dvbc_modulation_list[] = { +	{ "QAM16",   DVBFE_DVBC_MOD_QAM_16  }, +	{ "QAM32",   DVBFE_DVBC_MOD_QAM_32  }, +	{ "QAM64",   DVBFE_DVBC_MOD_QAM_64  }, +	{ "QAM128",  DVBFE_DVBC_MOD_QAM_128 }, +	{ "QAM256",  DVBFE_DVBC_MOD_QAM_256 }, +	{ "AUTO", DVBFE_DVBC_MOD_AUTO    }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_bandwidth_list[] = { +	{ "6MHz", DVBFE_DVBT_BANDWIDTH_6_MHZ }, +	{ "7MHz", DVBFE_DVBT_BANDWIDTH_7_MHZ }, +	{ "8MHz", DVBFE_DVBT_BANDWIDTH_8_MHZ }, +	{ "AUTO",  DVBFE_DVBT_BANDWIDTH_AUTO  }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_constellation_list[] = { +	{ "QAM16",   DVBFE_DVBT_CONST_QAM_16  }, +	{ "QAM32",   DVBFE_DVBT_CONST_QAM_32  }, +	{ "QAM64",   DVBFE_DVBT_CONST_QAM_64  }, +	{ "QAM128",  DVBFE_DVBT_CONST_QAM_128 }, +	{ "QAM256",  DVBFE_DVBT_CONST_QAM_256 }, +	{ "QPSK",     DVBFE_DVBT_CONST_QPSK    }, +	{ "AUTO", DVBFE_DVBT_CONST_AUTO    }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_transmission_mode_list[] = { +	{ "2k",   DVBFE_DVBT_TRANSMISSION_MODE_2K   }, +	{ "8k",   DVBFE_DVBT_TRANSMISSION_MODE_8K   }, +	{ "AUTO", DVBFE_DVBT_TRANSMISSION_MODE_AUTO }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_guard_interval_list[] = { +	{ "1/32", DVBFE_DVBT_GUARD_INTERVAL_1_32 }, +	{ "1/16", DVBFE_DVBT_GUARD_INTERVAL_1_16 }, +	{ "1/8",  DVBFE_DVBT_GUARD_INTERVAL_1_8  }, +	{ "1/4",  DVBFE_DVBT_GUARD_INTERVAL_1_4  }, +	{ "AUTO", DVBFE_DVBT_GUARD_INTERVAL_AUTO }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_hierarchy_list[] = { +	{ "1",    DVBFE_DVBT_HIERARCHY_1    }, +	{ "2",    DVBFE_DVBT_HIERARCHY_2    }, +	{ "4",    DVBFE_DVBT_HIERARCHY_4    }, +	{ "AUTO", DVBFE_DVBT_HIERARCHY_AUTO }, +	{ "NONE", DVBFE_DVBT_HIERARCHY_NONE }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_atsc_modulation_list[] = { +	{ "8VSB",    DVBFE_ATSC_MOD_VSB_8   }, +	{ "16VSB",   DVBFE_ATSC_MOD_VSB_16  }, +	{ "QAM64",  DVBFE_ATSC_MOD_QAM_64  }, +	{ "QAM256", DVBFE_ATSC_MOD_QAM_256 }, +	{ NULL, 0 } +}; + +int dvbcfg_scanfile_parse(FILE *file, dvbcfg_scancallback callback, void *private_data) +{ +	char *line_buf = NULL; +	size_t line_size = 0; +	int line_len = 0; +	int ret_val = 0; + +	while ((line_len = getline(&line_buf, &line_size, file)) > 0) { +		char *line_tmp = line_buf; +		char *line_pos = line_buf; +		struct dvbcfg_scanfile tmp; + +		/* remove newline and comments (started with hashes) */ +		while ((*line_tmp != '\0') && (*line_tmp != '\n') && (*line_tmp != '#')) +			line_tmp++; +		*line_tmp = '\0'; + +		/* always use inversion auto */ +		tmp.fe_params.inversion = DVBFE_INVERSION_AUTO; + +		/* parse frontend type */ +		switch(dvbcfg_parse_char(&line_pos, " ")) { +		case 'T': +			tmp.fe_type = DVBFE_TYPE_DVBT; +			break; +		case 'C': +			tmp.fe_type = DVBFE_TYPE_DVBC; +			break; +		case 'S': +			tmp.fe_type = DVBFE_TYPE_DVBS; +			break; +		case 'A': +			tmp.fe_type = DVBFE_TYPE_ATSC; +			break; +		default: +			continue; +		} + +		/* parse frontend specific settings */ +		switch (tmp.fe_type) { +		case DVBFE_TYPE_ATSC: + +			/* parse frequency */ +			tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, " "); +			if (!line_pos) +				continue; + +			/* modulation */ +			tmp.fe_params.u.atsc.modulation = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_atsc_modulation_list); +			if (!line_pos) +				continue; + +			break; + +		case DVBFE_TYPE_DVBC: + +			/* parse frequency */ +			tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, " "); +			if (!line_pos) +				continue; + +			/* symbol rate */ +			tmp.fe_params.u.dvbc.symbol_rate = dvbcfg_parse_int(&line_pos, " "); +			if (!line_pos) +				continue; + +			/* fec */ +			tmp.fe_params.u.dvbc.fec_inner = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_fec_list); +			if (!line_pos) +				continue; + +			/* modulation */ +			tmp.fe_params.u.dvbc.modulation = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_dvbc_modulation_list); +			if (!line_pos) +				continue; + +			break; + +		case DVBFE_TYPE_DVBS: + +			/* parse frequency */ +			tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, " "); +			if (!line_pos) +				continue; + +			/* polarization */ +			tmp.polarization = tolower(dvbcfg_parse_char(&line_pos, " ")); +			if (!line_pos) +				continue; +			if ((tmp.polarization != 'h') && +			    (tmp.polarization != 'v') && +			    (tmp.polarization != 'l') && +			    (tmp.polarization != 'r')) +				continue; + +			/* symbol rate */ +			tmp.fe_params.u.dvbs.symbol_rate = dvbcfg_parse_int(&line_pos, " "); +			if (!line_pos) +				continue; + +			/* fec */ +			tmp.fe_params.u.dvbc.fec_inner = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_fec_list); +			if (!line_pos) +				continue; + +			break; + +		case DVBFE_TYPE_DVBT: + +			/* parse frequency */ +			tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, " "); +			if (!line_pos) +				continue; + +			/* bandwidth */ +			tmp.fe_params.u.dvbt.bandwidth = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_bandwidth_list); +			if (!line_pos) +				continue; + +			/* fec hp */ +			tmp.fe_params.u.dvbt.code_rate_HP = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_fec_list); +			if (!line_pos) +				continue; + +			/* fec lp */ +			tmp.fe_params.u.dvbt.code_rate_LP = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_fec_list); +			if (!line_pos) +				continue; + +			/* constellation */ +			tmp.fe_params.u.dvbt.constellation = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_constellation_list); +			if (!line_pos) +				continue; + +			/* transmission mode */ +			tmp.fe_params.u.dvbt.transmission_mode = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_transmission_mode_list); +			if (!line_pos) +				continue; + +			/* guard interval */ +			tmp.fe_params.u.dvbt.guard_interval = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_guard_interval_list); +			if (!line_pos) +				continue; + +			/* hierarchy */ +			tmp.fe_params.u.dvbt.hierarchy_information = +				dvbcfg_parse_setting(&line_pos, " ", dvbcfg_hierarchy_list); +			if (!line_pos) +				continue; + +			break; +		} + +		/* invoke callback */ +		if ((ret_val = callback(&tmp, private_data)) != 0) { +			if (ret_val < 0) +				ret_val = 0; +			break; +		} +	} + +	if (line_buf) +		free(line_buf); + +	return ret_val; +} diff --git a/lib/libdvbcfg/dvbcfg_scanfile.h b/lib/libdvbcfg/dvbcfg_scanfile.h new file mode 100644 index 0000000..d7a20b1 --- /dev/null +++ b/lib/libdvbcfg/dvbcfg_scanfile.h @@ -0,0 +1,61 @@ +/* + * dvbcfg - support for linuxtv configuration files + * scan channel file support + * + * Copyright (C) 2006 Andrew de Quincey <adq_dvb@lidskialf.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DVBCFG_SCANFILE_H +#define DVBCFG_SCANFILE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libdvbapi/dvbfe.h> +#include <stdio.h> + +struct dvbcfg_scanfile { +	enum dvbfe_type fe_type; +	struct dvbfe_parameters fe_params; +	char polarization; /* l,r,v,h - only used for dvb-s */ +}; + +/** + * Callback used in dvbcfg_scanfile_parse() + * + * @param channel Selected channel + * @param private_data Private data for the callback + * @return 0 to continue, other values to stop (values > 0 are forwarded; see below) + */ +typedef int (*dvbcfg_scancallback)(struct dvbcfg_scanfile *channel, void *private_data); + +/** + * Parse a linuxtv scan file + * + * @param file Linuxtv scan file + * @param callback Callback called for each scan entry + * @param private_data Private data for the callback + * @return on success 0 or value from the callback if it's > 0, error code on failure + */ +extern int dvbcfg_scanfile_parse(FILE *file, dvbcfg_scancallback callback, void *private_data); + +#ifdef __cplusplus +} +#endif + +#endif /* DVBCFG_SCANFILE_H */ diff --git a/lib/libdvbcfg/dvbcfg_zapchannel.c b/lib/libdvbcfg/dvbcfg_zapchannel.c new file mode 100644 index 0000000..2c2605e --- /dev/null +++ b/lib/libdvbcfg/dvbcfg_zapchannel.c @@ -0,0 +1,384 @@ +/* + * dvbcfg - support for linuxtv configuration files + * zap channel file support + * + * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com> + * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define _GNU_SOURCE + +#include <malloc.h> +#include <string.h> +#include <ctype.h> + +#include "dvbcfg_zapchannel.h" +#include "dvbcfg_common.h" + +static const struct dvbcfg_setting dvbcfg_inversion_list[] = { +	{ "INVERSION_ON",   DVBFE_INVERSION_ON   }, +	{ "INVERSION_OFF",  DVBFE_INVERSION_OFF  }, +	{ "INVERSION_AUTO", DVBFE_INVERSION_AUTO }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_fec_list[] = { +	{ "FEC_1_2",  DVBFE_FEC_1_2  }, +	{ "FEC_2_3",  DVBFE_FEC_2_3  }, +	{ "FEC_3_4",  DVBFE_FEC_3_4  }, +	{ "FEC_4_5",  DVBFE_FEC_4_5  }, +	{ "FEC_5_6",  DVBFE_FEC_5_6  }, +	{ "FEC_6_7",  DVBFE_FEC_6_7  }, +	{ "FEC_7_8",  DVBFE_FEC_7_8  }, +	{ "FEC_8_9",  DVBFE_FEC_8_9  }, +	{ "FEC_AUTO", DVBFE_FEC_AUTO }, +	{ "FEC_NONE", DVBFE_FEC_NONE }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_dvbc_modulation_list[] = { +	{ "QAM_16",   DVBFE_DVBC_MOD_QAM_16  }, +	{ "QAM_32",   DVBFE_DVBC_MOD_QAM_32  }, +	{ "QAM_64",   DVBFE_DVBC_MOD_QAM_64  }, +	{ "QAM_128",  DVBFE_DVBC_MOD_QAM_128 }, +	{ "QAM_256",  DVBFE_DVBC_MOD_QAM_256 }, +	{ "QAM_AUTO", DVBFE_DVBC_MOD_AUTO    }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_bandwidth_list[] = { +	{ "BANDWIDTH_6_MHZ", DVBFE_DVBT_BANDWIDTH_6_MHZ }, +	{ "BANDWIDTH_7_MHZ", DVBFE_DVBT_BANDWIDTH_7_MHZ }, +	{ "BANDWIDTH_8_MHZ", DVBFE_DVBT_BANDWIDTH_8_MHZ }, +	{ "BANDWIDTH_AUTO",  DVBFE_DVBT_BANDWIDTH_AUTO  }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_constellation_list[] = { +	{ "QAM_16",   DVBFE_DVBT_CONST_QAM_16  }, +	{ "QAM_32",   DVBFE_DVBT_CONST_QAM_32  }, +	{ "QAM_64",   DVBFE_DVBT_CONST_QAM_64  }, +	{ "QAM_128",  DVBFE_DVBT_CONST_QAM_128 }, +	{ "QAM_256",  DVBFE_DVBT_CONST_QAM_256 }, +	{ "QPSK",     DVBFE_DVBT_CONST_QPSK    }, +	{ "QAM_AUTO", DVBFE_DVBT_CONST_AUTO    }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_transmission_mode_list[] = { +	{ "TRANSMISSION_MODE_2K",   DVBFE_DVBT_TRANSMISSION_MODE_2K   }, +	{ "TRANSMISSION_MODE_8K",   DVBFE_DVBT_TRANSMISSION_MODE_8K   }, +	{ "TRANSMISSION_MODE_AUTO", DVBFE_DVBT_TRANSMISSION_MODE_AUTO }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_guard_interval_list[] = { +	{ "GUARD_INTERVAL_1_32", DVBFE_DVBT_GUARD_INTERVAL_1_32 }, +	{ "GUARD_INTERVAL_1_16", DVBFE_DVBT_GUARD_INTERVAL_1_16 }, +	{ "GUARD_INTERVAL_1_8",  DVBFE_DVBT_GUARD_INTERVAL_1_8  }, +	{ "GUARD_INTERVAL_1_4",  DVBFE_DVBT_GUARD_INTERVAL_1_4  }, +	{ "GUARD_INTERVAL_AUTO", DVBFE_DVBT_GUARD_INTERVAL_AUTO }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_hierarchy_list[] = { +	{ "HIERARCHY_1",    DVBFE_DVBT_HIERARCHY_1    }, +	{ "HIERARCHY_2",    DVBFE_DVBT_HIERARCHY_2    }, +	{ "HIERARCHY_4",    DVBFE_DVBT_HIERARCHY_4    }, +	{ "HIERARCHY_AUTO", DVBFE_DVBT_HIERARCHY_AUTO }, +	{ "HIERARCHY_NONE", DVBFE_DVBT_HIERARCHY_NONE }, +	{ NULL, 0 } +}; + +static const struct dvbcfg_setting dvbcfg_atsc_modulation_list[] = { +	{ "8VSB",    DVBFE_ATSC_MOD_VSB_8   }, +	{ "16VSB",   DVBFE_ATSC_MOD_VSB_16  }, +	{ "QAM_64",  DVBFE_ATSC_MOD_QAM_64  }, +	{ "QAM_256", DVBFE_ATSC_MOD_QAM_256 }, +	{ NULL, 0 } +}; + +int dvbcfg_zapchannel_parse(FILE *file, dvbcfg_zapcallback callback, void *private_data) +{ +	char *line_buf = NULL; +	size_t line_size = 0; +	int line_len = 0; +	int ret_val = 0; + +	while ((line_len = getline(&line_buf, &line_size, file)) > 0) { +		char *line_tmp = line_buf; +		char *line_pos = line_buf; +		struct dvbcfg_zapchannel tmp; + +		/* remove newline and comments (started with hashes) */ +		while ((*line_tmp != '\0') && (*line_tmp != '\n') && (*line_tmp != '#')) +			line_tmp++; +		*line_tmp = '\0'; + +		/* parse name */ +		dvbcfg_parse_string(&line_pos, ":", tmp.name, sizeof(tmp.name)); +		if (!line_pos) +			continue; + +		/* parse frequency */ +		tmp.fe_params.frequency = dvbcfg_parse_int(&line_pos, ":"); +		if (!line_pos) +			continue; + +		/* try to determine frontend type */ +		if (strstr(line_pos, ":FEC_")) { +			if (strstr(line_pos, ":HIERARCHY_")) +				tmp.fe_type = DVBFE_TYPE_DVBT; +			else +				tmp.fe_type = DVBFE_TYPE_DVBC; +		} else { +			if (strstr(line_pos, "VSB:") || strstr(line_pos, "QAM_")) +				tmp.fe_type = DVBFE_TYPE_ATSC; +			else +				tmp.fe_type = DVBFE_TYPE_DVBS; +		} + +		/* parse frontend specific settings */ +		switch (tmp.fe_type) { +		case DVBFE_TYPE_ATSC: +			/* inversion */ +			tmp.fe_params.inversion = DVBFE_INVERSION_AUTO; + +			/* modulation */ +			tmp.fe_params.u.atsc.modulation = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_atsc_modulation_list); +			if (!line_pos) +				continue; + +			break; + +		case DVBFE_TYPE_DVBC: +			/* inversion */ +			tmp.fe_params.inversion = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_inversion_list); +			if (!line_pos) +				continue; + +			/* symbol rate */ +			tmp.fe_params.u.dvbc.symbol_rate = dvbcfg_parse_int(&line_pos, ":"); +			if (!line_pos) +				continue; + +			/* fec */ +			tmp.fe_params.u.dvbc.fec_inner = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_fec_list); +			if (!line_pos) +				continue; + +			/* modulation */ +			tmp.fe_params.u.dvbc.modulation = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_dvbc_modulation_list); +			if (!line_pos) +				continue; + +			break; + +		case DVBFE_TYPE_DVBS: +			/* adjust frequency */ +			tmp.fe_params.frequency *= 1000; + +			/* inversion */ +			tmp.fe_params.inversion = DVBFE_INVERSION_AUTO; + +			/* fec */ +			tmp.fe_params.u.dvbs.fec_inner = DVBFE_FEC_AUTO; + +			/* polarization */ +			tmp.polarization = tolower(dvbcfg_parse_char(&line_pos, ":")); +			if (!line_pos) +				continue; +			if ((tmp.polarization != 'h') && +			    (tmp.polarization != 'v') && +			    (tmp.polarization != 'l') && +			    (tmp.polarization != 'r')) +				continue; + +			/* satellite switch position */ +			tmp.diseqc_switch = dvbcfg_parse_int(&line_pos, ":"); +			if (!line_pos) +				continue; + +			/* symbol rate */ +			tmp.fe_params.u.dvbs.symbol_rate = +				dvbcfg_parse_int(&line_pos, ":") * 1000; +			if (!line_pos) +				continue; + +			break; + +		case DVBFE_TYPE_DVBT: +			/* inversion */ +			tmp.fe_params.inversion = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_inversion_list); +			if (!line_pos) +				continue; + +			/* bandwidth */ +			tmp.fe_params.u.dvbt.bandwidth = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_bandwidth_list); +			if (!line_pos) +				continue; + +			/* fec hp */ +			tmp.fe_params.u.dvbt.code_rate_HP = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_fec_list); +			if (!line_pos) +				continue; + +			/* fec lp */ +			tmp.fe_params.u.dvbt.code_rate_LP = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_fec_list); +			if (!line_pos) +				continue; + +			/* constellation */ +			tmp.fe_params.u.dvbt.constellation = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_constellation_list); +			if (!line_pos) +				continue; + +			/* transmission mode */ +			tmp.fe_params.u.dvbt.transmission_mode = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_transmission_mode_list); +			if (!line_pos) +				continue; + +			/* guard interval */ +			tmp.fe_params.u.dvbt.guard_interval = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_guard_interval_list); +			if (!line_pos) +				continue; + +			/* hierarchy */ +			tmp.fe_params.u.dvbt.hierarchy_information = +				dvbcfg_parse_setting(&line_pos, ":", dvbcfg_hierarchy_list); +			if (!line_pos) +				continue; + +			break; +		} + +		/* parse video and audio pids and service id */ +		tmp.video_pid = dvbcfg_parse_int(&line_pos, ":"); +		if (!line_pos) +			continue; +		tmp.audio_pid = dvbcfg_parse_int(&line_pos, ":"); +		if (!line_pos) +			continue; +		tmp.service_id = dvbcfg_parse_int(&line_pos, ":"); +		if (!line_pos) /* old files don't have a service id */ +			tmp.service_id = 0; + +		/* invoke callback */ +		if ((ret_val = callback(&tmp, private_data)) != 0) { +			if (ret_val < 0) +				ret_val = 0; +			break; +		} +	} + +	if (line_buf) +		free(line_buf); + +	return ret_val; +} + +int dvbcfg_zapchannel_save(FILE *file, dvbcfg_zapcallback callback, void *private_data) +{ +	int ret_val = 0; +	struct dvbcfg_zapchannel tmp; + +	while ((ret_val = callback(&tmp, private_data)) == 0) { +		/* name */ +		if ((ret_val = fprintf(file, "%s:", tmp.name)) < 0) +			return ret_val; + +		/* frontend specific settings */ +		switch (tmp.fe_type) { +		case DVBFE_TYPE_ATSC: +			if ((ret_val = fprintf(file, "%i:%s:", +			    tmp.fe_params.frequency, +			    dvbcfg_lookup_setting(tmp.fe_params.u.atsc.modulation, +						  dvbcfg_atsc_modulation_list))) < 0) +				return ret_val; + +			break; + +		case DVBFE_TYPE_DVBC: +			if ((ret_val = fprintf(file, "%i:%s:%i:%s:%s:", +			    tmp.fe_params.frequency, +			    dvbcfg_lookup_setting(tmp.fe_params.inversion, +						  dvbcfg_inversion_list), +			    tmp.fe_params.u.dvbc.symbol_rate, +			    dvbcfg_lookup_setting(tmp.fe_params.u.dvbc.fec_inner, +						  dvbcfg_fec_list), +			    dvbcfg_lookup_setting(tmp.fe_params.u.dvbc.modulation, +						  dvbcfg_dvbc_modulation_list))) < 0) +				return ret_val; + +			break; + +		case DVBFE_TYPE_DVBS: +			if ((ret_val = fprintf(file, "%i:%c:%i:%i:", +			    tmp.fe_params.frequency / 1000, +			    tolower(tmp.polarization), +			    tmp.diseqc_switch, +			    tmp.fe_params.u.dvbs.symbol_rate / 1000)) < 0) +				return ret_val; + +			break; +		case DVBFE_TYPE_DVBT: +			if ((ret_val = fprintf(file, "%i:%s:%s:%s:%s:%s:%s:%s:%s:", +			    tmp.fe_params.frequency, +			    dvbcfg_lookup_setting(tmp.fe_params.inversion, +						  dvbcfg_inversion_list), +			    dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.bandwidth, +						  dvbcfg_bandwidth_list), +			    dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.code_rate_HP, +						  dvbcfg_fec_list), +			    dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.code_rate_LP, +						  dvbcfg_fec_list), +			    dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.constellation, +						  dvbcfg_constellation_list), +			    dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.transmission_mode, +						  dvbcfg_transmission_mode_list), +			    dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.guard_interval, +						  dvbcfg_guard_interval_list), +			    dvbcfg_lookup_setting(tmp.fe_params.u.dvbt.hierarchy_information, +						  dvbcfg_hierarchy_list))) < 0) +				return ret_val; + +			break; +		} + +		/* video and audio pids and service id */ +		if ((ret_val = fprintf(file, "%i:%i:%i\n", +		    tmp.video_pid, tmp.audio_pid, tmp.service_id)) < 0) +			return ret_val; + +	} + +	if (ret_val < 0) +		ret_val = 0; + +	return ret_val; +} diff --git a/lib/libdvbcfg/dvbcfg_zapchannel.h b/lib/libdvbcfg/dvbcfg_zapchannel.h new file mode 100644 index 0000000..67ec62e --- /dev/null +++ b/lib/libdvbcfg/dvbcfg_zapchannel.h @@ -0,0 +1,77 @@ +/* + * dvbcfg - support for linuxtv configuration files + * zap channel file support + * + * Copyright (C) 2006 Christoph Pfister <christophpfister@gmail.com> + * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef DVBCFG_ZAPCHANNEL_H +#define DVBCFG_ZAPCHANNEL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libdvbapi/dvbfe.h> +#include <stdio.h> + +struct dvbcfg_zapchannel { +	char name[128]; +	int video_pid; +	int audio_pid; +	int service_id; +	enum dvbfe_type fe_type; +	struct dvbfe_parameters fe_params; +	char polarization; /* l,r,v,h - only used for dvb-s */ +	int diseqc_switch; /* only used for dvb-s */ +}; + +/** + * Callback used in dvbcfg_zapchannel_parse() and dvbcfg_zapchannel_save() + * + * @param channel Selected channel + * @param private_data Private data for the callback + * @return 0 to continue, other values to stop (values > 0 are forwarded; see below) + */ +typedef int (*dvbcfg_zapcallback)(struct dvbcfg_zapchannel *channel, void *private_data); + +/** + * Parse a linuxtv channel file + * + * @param file Linuxtv channel file + * @param callback Callback called for each channel + * @param private_data Private data for the callback + * @return on success 0 or value from the callback if it's > 0, error code on failure + */ +extern int dvbcfg_zapchannel_parse(FILE *file, dvbcfg_zapcallback callback, void *private_data); + +/** + * Save to a linuxtv channel file + * + * @param file Linuxtv channel file + * @param callback Callback called for each channel + * @param private_data Private data for the callback + * @return on success 0 or value from the callback if it's > 0, error code on failure + */ +extern int dvbcfg_zapchannel_save(FILE *file, dvbcfg_zapcallback callback, void *private_data); + +#ifdef __cplusplus +} +#endif + +#endif /* DVBCFG_ZAPCHANNEL_H */ diff --git a/lib/libdvbcfg/zapchannel.txt b/lib/libdvbcfg/zapchannel.txt new file mode 100644 index 0000000..cdfdb87 --- /dev/null +++ b/lib/libdvbcfg/zapchannel.txt @@ -0,0 +1,72 @@ +/** + * The zapchannel file format specifies tuning parameters for channels. Each line describes + * a single channel, and consists of multiple options separated by ':'. The exact + * format of each line depends on the DVB type of the channel (i.e. DVBS, DVBT, DVBC, or ATSC). + * + * Note: the lines have been split across multiple lines in the following due to length issues. + * + * The format for DVBT channels is: + * + * <name>:<frequency>:<inversion>:<bandwidth>:<fec_hp>:<fec_lp>: + * <constellation>:<transmission>:<guard_interval>:<hierarchy>: + * <video_pid>:<audio_pid>:<channel_number> + * + * 	name: name of the channel + * 	frequency: frequency in Hz + * 	inversion: one of INVERSION_OFF, INVERSION_ON, or INVERSION_AUTO. + * 	bandwidth: one of BANDWIDTH_6_MHZ, BANDWIDTH_7_MHZ, or BANDWIDTH_8_MHZ. + * 	fec_hp: FEC of the high priority stream, one of: FEC_1_2, FEC_2_3, + * 		FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8, FEC_8_9, or FEC_AUTO. + * 	fec_lp: FEC of the low priority stream, one of: FEC_1_2, FEC_2_3, + * 		FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8, FEC_8_9, FEC_AUTO, or FEC_NONE. + * 	constellation: one of QPSK, QAM_128, QAM_16, QAM_256, QAM_32, or QAM_64. + * 	transmission: one of TRANSMISSION_MODE_2K, or TRANSMISSION_MODE_8K. + * 	guard_interval: one of GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16, GUARD_INTERVAL_1_8, or GUARD_INTERVAL_1_4. + * 	hierarchy: one of HIERARCHY_NONE, HIERARCHY_1, HIERARCHY_2, or HIERARCHY_4. + * 	video_pid: PID of the video stream. + * 	audio_pid: PID of the audio stream. + * 	channel_number: Transport stream channel number of the program. + * + * DVBC: + * + * <name>:<frequency>:<inversion>:<symbol_rate>:<fec>: + * <modulation>:<video_pid>:<audio_pid>:<channel_number> + * + * 	name: name of the channel + * 	frequency: frequency in Hz + * 	inversion: one of INVERSION_OFF, INVERSION_ON, or INVERSION_AUTO. + * 	symbol_rate: Symbol rate of the channel in ksyms. + * 	fec: One of: FEC_1_2, FEC_2_3, FEC_3_4, FEC_4_5, FEC_5_6, FEC_6_7, + * 			FEC_7_8, FEC_8_9, or FEC_AUTO. + * 	modulation: one of QAM_16, QAM_32, QAM_64, QAM_128, QAM_256, QAM_AUTO. + * 	video_pid: PID of the video stream. + * 	audio_pid: PID of the audio stream. + * 	channel_number: Transport stream channel number of the program. + * + * DVBS: + * + * <name>:<frequency>:<polarization>:<satellite_switches>:<symbol_rate>:<video_pid>:<audio_pid>:<channel_number> + * + * 	name: name of the channel + * 	frequency: frequency in kHz + * 	polarization: one of H,V,L, or R. + * 	satellite_switches: Treated as a 2 bit value controlling switches in SEC equipment: + * 		bit 0: controls "satellite switch", 0: A, 1: B + * 		bit 1: controls "switch option", 0: A, 1: B + * 	symbol_rate: Symbol rate of the channel in ksyms. + * 	video_pid: PID of the video stream. + * 	audio_pid: PID of the audio stream. + * 	channel_number: Transport stream channel number of the program. + * + * ATSC: + * + * <name>:<frequency>:<inversion>:<modulation>:<video_pid>:<audio_pid>:<channel_number> + * + * 	name: name of the channel + * 	frequency: frequency in GHz + * 	inversion: one of INVERSION_OFF, INVERSION_ON, or INVERSION_AUTO. + * 	modulation: one of 8VSB, 16VSB, QAM_64, or QAM_256. + * 	video_pid: PID of the video stream. + * 	audio_pid: PID of the audio stream. + * 	channel_number: Transport stream channel number of the program. + */ | 
