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-upstream/1.1.1+rev1207.tar.gz |
Imported Upstream version 1.1.1+rev1207upstream/1.1.1+rev1207
Diffstat (limited to '')
-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. + */ |