Andrew de Quincey wrote: >>Attached is my current channels.conf and a hacked version of scan which >>prints out the service_id at the very end. It is not a big problem to >>add in to parse the VDR format too, as i had a parser for the Metzler's >>libdvb format also, but temporarily removed of all those bells and >>whistles to make testing and debugging easier.. > > I'd be interested in helping with parsing the file formats to start with - if > they were to be exported into a seperate library that is. > > What i had been doing was ca_zap was split up into 2 libs. One for parsing si and the other just creating EN50221 style commands for the driver.. Eventhough, my original idea was that channels.c and filter.c goes to dvb-apps/util/lib, along with lnb.c in similar lines dvb-apps/util/libsi dvb-apps/util/liben50221 dvb-apps/util/ca_zap but temporarily to test out ca_zap, i have filter.c and channels.c in libsi itself to make matters simple for me at the moment.. > > Looking at VDR 1.26 there are three config files: > > sources.conf. This contains a description of the source of the transmission - > the satellite/Dvbt/dvbc transmitter: > > S19.2E Astra 1B/C/E/F/G/H/2C > S21.5E Eutelsat II F3 > S23.5E Astra 3A > S24.2E Astra 1D > > (you use T and C prefixes for terrestial, and cable respectively) > > > This is referred to from diseqc.conf, which lets the user specify how to tune > to a signal to that source: > > S19.2E 11700 V 9750 t v W15 [E0 10 38 F0] W15 A W15 t > S19.2E 99999 V 10600 t v W15 [E0 10 38 F1] W15 A W15 T > S19.2E 11700 H 9750 t V W15 [E0 10 38 F2] W15 A W15 t > S19.2E 99999 H 10600 t V W15 [E0 10 38 F3] W15 A W15 T > > The above specifies how/what diseqc/tone/voltage commands to send for the four > "bands" for Astra 1B/C/E/F/G/H/2C.. the format is as follows: > > # satellite: one of the 'S' codes defined in sources.conf > # slof: switch frequency of LNB; the first entry with > # an slof greater than the actual transponder > # frequency will be used > # polarization: V = vertical, H = horizontal > # lof: the local oscillator frequency to subtract from > # the actual transponder frequency > # command: > # t tone off > # T tone on > # v voltage low (13V) > # V voltage high (18V) > # A mini A > # B mini B > # Wnn wait nn milliseconds (nn may be any positive integer number) > # [xx ...] hex code sequence (max. 6) > > > Finally, channels, conf refers to sources.conf directly, and looks up the > appropriate entry in diseqc.conf to know what diseqc stuff to use: > > RTL:12188:h:S19.2E:27500:163:104:105:0:12003:0:0:0 > > So RTL is at freq 12188, h polarization on source S192.E... you can guess the > rest. I will take a look at it .. Manu -------------- next part -------------- /* channels.conf parser an implementation for the High Level Common Interface Copyright (C) 2004, 2005 Manu Abraham (manu@xxxxxxxxxxx) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include <stdio.h> #include <stdint.h> #include <string.h> #include "channels.h" typedef struct { char *name; int value; } param; // DVB-C static const param inversion_list[] = { { "INVERSION_OFF", INVERSION_OFF }, { "INVERSION_ON", INVERSION_ON }, { "INVERSION_AUTO", INVERSION_AUTO } }; static const param fec_list[] = { { "FEC_1_2", FEC_1_2 }, { "FEC_2_3", FEC_2_3 }, { "FEC_3_4", FEC_3_4 }, { "FEC_4_5", FEC_4_5 }, { "FEC_5_6", FEC_5_6 }, { "FEC_6_7", FEC_6_7 }, { "FEC_7_8", FEC_7_8 }, { "FEC_8_9", FEC_8_9 }, { "FEC_AUTO", FEC_AUTO }, { "FEC_NONE", FEC_NONE } }; static const param modulation_list[] = { { "QAM_16", QAM_16 }, { "QAM_32", QAM_32 }, { "QAM_64", QAM_64 }, { "QAM_128", QAM_128 }, { "QAM_256", QAM_256 }, { "QAM_AUTO", QAM_AUTO } }; // DVB-T static const param bandwidth_list [] = { { "BANDWIDTH_6_MHZ", BANDWIDTH_6_MHZ }, { "BANDWIDTH_7_MHZ", BANDWIDTH_7_MHZ }, { "BANDWIDTH_8_MHZ", BANDWIDTH_8_MHZ } }; static const param guard_interval_list [] = { {"GUARD_INTERVAL_1_16", GUARD_INTERVAL_1_16}, {"GUARD_INTERVAL_1_32", GUARD_INTERVAL_1_32}, {"GUARD_INTERVAL_1_4", GUARD_INTERVAL_1_4}, {"GUARD_INTERVAL_1_8", GUARD_INTERVAL_1_8} }; static const param hierarchy_list [] = { { "HIERARCHY_1", HIERARCHY_1 }, { "HIERARCHY_2", HIERARCHY_2 }, { "HIERARCHY_4", HIERARCHY_4 }, { "HIERARCHY_NONE", HIERARCHY_NONE } }; static const param constellation_list [] = { { "QPSK", QPSK }, { "QAM_128", QAM_128 }, { "QAM_16", QAM_16 }, { "QAM_256", QAM_256 }, { "QAM_32", QAM_32 }, { "QAM_64", QAM_64 } }; static const param transmission_mode_list [] = { { "TRANSMISSION_MODE_2K", TRANSMISSION_MODE_2K }, { "TRANSMISSION_MODE_8K", TRANSMISSION_MODE_8K }, }; #define LIST_SIZE(x) sizeof(x)/sizeof(param) static int parse_param(char *val, const param *p_list, int list_size) { int i; for (i = 0; i < list_size; i++) { if (strcasecmp(p_list[i].name, val) == 0) return p_list[i].value; } return -1; } static int parse_ter_channel_list(struct channel_params *p_channel_params, char *channel_list_file, char *channel_name, FILE *channel_list_fd) { char buffer[80]; while ((fgets(buffer, sizeof (buffer), channel_list_fd)) != NULL) { strcpy(p_channel_params->channel, (char *) strtok(buffer, ":")); p_channel_params->frequency = strtoul(strtok('\0', ":"), NULL, 0 ); p_channel_params->inversion = parse_param(strtok('\0', ":"), inversion_list, LIST_SIZE(inversion_list)); if (p_channel_params->inversion < 0) { printf("ERROR: inversion field syntax error\n"); return -1; } p_channel_params->bandwidth = parse_param(strtok('\0', ":"), bandwidth_list, LIST_SIZE(bandwidth_list)); if (p_channel_params->bandwidth < 0) { printf("ERROR: bandwidth field syntax error\n"); return -1; } p_channel_params->code_rate_hp = parse_param(strtok('\0', ":"), fec_list, LIST_SIZE(fec_list)); if (p_channel_params->code_rate_hp < 0) { printf("ERROR: fec_inner field syntax error\n"); return -1; } p_channel_params->code_rate_lp = parse_param(strtok('\0', ":"), fec_list, LIST_SIZE(fec_list)); if (p_channel_params->code_rate_lp < 0) { printf("ERROR: fec_outer field syntax error\n"); return -1; } p_channel_params->constellation = parse_param(strtok('\0', ":"), constellation_list, LIST_SIZE(constellation_list)); if (p_channel_params->constellation < 0) { printf("ERROR: modulation field syntax error\n"); return -1; } p_channel_params->transmission_mode = parse_param(strtok('\0', ":"), transmission_mode_list, LIST_SIZE(transmission_mode_list)); if (p_channel_params->transmission_mode < 0) { printf("ERROR: transmission_mode field syntax error\n"); return -1; } p_channel_params->guard_interval = parse_param(strtok('\0', ":"), guard_interval_list, LIST_SIZE(guard_interval_list)); if (p_channel_params->guard_interval < 0) { printf("ERROR: guard_interval field syntax error\n"); return -1; } p_channel_params->hierarchy = parse_param(strtok('\0', ":"), hierarchy_list, LIST_SIZE(hierarchy_list)); if (p_channel_params->hierarchy < 0) { printf("ERROR: hierarchy field syntax error\n"); return -1; } p_channel_params->video_pid = strtoul(strtok('\0', ":"), NULL, 0 ); p_channel_params->audio_pid = strtoul(strtok('\0', ":"), NULL, 0 ); p_channel_params->service_id = strtoul(strtok('\0', ":"), NULL, 0 ); } return 0; } static int parse_cab_channel_list(struct channel_params *p_channel_params, char *channel_list_file, char *channel_name, FILE *channel_list_fd) { char buffer[80]; while ((fgets(buffer, sizeof (buffer), channel_list_fd)) != NULL) { strcpy(p_channel_params->channel, strtok(buffer, ":")); p_channel_params->frequency = strtoul(strtok('\0', ":"), NULL, 0); p_channel_params->inversion = parse_param(strtok('\0', ":"), inversion_list, LIST_SIZE(inversion_list)); if (p_channel_params->inversion < 0) { printf("ERROR: inversion field syntax error\n"); return -1; } p_channel_params->symbol_rate = strtoul((strtok('\0', ":")), NULL, 0); p_channel_params->fec = parse_param(strtok('\0', ":"), fec_list, LIST_SIZE(fec_list)); if (p_channel_params->fec < 0) { printf("ERROR: FEC field syntax error\n"); return -1; } p_channel_params->modulation = parse_param(strtok('\0', ":"), modulation_list, LIST_SIZE(modulation_list)); if (p_channel_params->modulation < 0) { printf("ERROR: modulation field syntax error\n"); return -1; } p_channel_params->video_pid = strtoul((strtok('\0', ":")), NULL, 0); p_channel_params->audio_pid = strtoul((strtok('\0', ":")), NULL, 0); p_channel_params->service_id = strtoul((strtok('\0', ":")), NULL, 0); // The old format does not have it ! } return 0; } static int parse_sat_channel_list(struct channel_params *p_channel_params, char *channel_list_file, char *channel_name, FILE *channel_list_fd) { int i, entries = 0; char buffer[80]; uint32_t service_id = 0; i = 0, entries = 0; while ((fgets(buffer, sizeof (buffer), channel_list_fd)) != NULL) { /* Tokenize each */ strcpy(p_channel_params->channel, strtok(buffer, ":")); p_channel_params->frequency = strtoul((strtok ('\0', ":")), NULL, 0); strcpy(&p_channel_params->polarity, strtok('\0', ":")); p_channel_params->sat_no = strtoul((strtok('\0', ":")), NULL, 0); p_channel_params->symbol_rate = strtoul((strtok ('\0', ":")), NULL, 0); p_channel_params->video_pid = strtoul((strtok ('\0', ":")), NULL, 0); p_channel_params->audio_pid = strtoul((strtok ('\0', ":")), NULL, 0); p_channel_params->service_id = strtoul((strtok ('\0', ":")), NULL, 0); if (!strcmp(channel_name, p_channel_params->channel)) { service_id = p_channel_params->service_id; printf("%s: Channel=[%s], Frequency=[%d], Satellite=[%d], Symbol Rate=[%d], Video=[%d], Audio=[%d], Service=[%d]\n", __FUNCTION__, p_channel_params->channel, p_channel_params->frequency, p_channel_params->sat_no, p_channel_params->symbol_rate, p_channel_params->video_pid, p_channel_params->audio_pid, p_channel_params->service_id); break; } } return 0; } uint16_t parse_channel_list(struct channel_params *p_channel_params, char *channel_list_file, char *channel_name, uint8_t fe_type) { FILE *channel_list_fd; if ((channel_list_fd = fopen(channel_list_file, "r")) == NULL) { printf ("File %s open failed.\n", channel_list_file); exit (-1); } printf("Parsing %s\n", channel_list_file); if (fe_type == 1) { printf("Satellite frontend\n"); parse_sat_channel_list(p_channel_params, channel_list_file, channel_name, channel_list_fd); printf("Service ID=[%d]\n", p_channel_params->service_id); } else if (fe_type == 2) { printf("Cable frontend\n"); parse_cab_channel_list(p_channel_params, channel_list_file, channel_name, channel_list_fd); printf("Service ID=[%d]\n", p_channel_params->service_id); } else if (fe_type == 3) { printf("Terrestrial frontend\n"); parse_ter_channel_list(p_channel_params, channel_list_file, channel_name, channel_list_fd); printf("Service ID=[%d]\n", p_channel_params->service_id); } fclose(channel_list_fd); return 0; } -------------- next part -------------- /* channels.conf parser an implementation for the High Level Common Interface Copyright (C) 2004, 2005 Manu Abraham (manu@xxxxxxxxxxx) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #ifndef __CHANNELS_H__ #define __CHANNELS_H__ #include <stdlib.h> #include <unistd.h> #include <linux/dvb/frontend.h> struct channel_params { char channel[20]; uint32_t frequency; char polarity; int inversion; uint8_t sat_no; int bandwidth; uint32_t symbol_rate; int fec; int code_rate_hp; int code_rate_lp; int modulation; int constellation; int transmission_mode; int guard_interval; int hierarchy; uint32_t video_pid; uint32_t audio_pid; uint32_t service_id; }; uint16_t parse_channel_list(struct channel_params *p_channel_params, char *channel_list_file, char *channel_name, uint8_t fe_type); #endif