/* Arrays from dvb-v5.h */
-extern const unsigned fe_bandwidth_name[7];
-extern const char *dvb_v5_name[45];
+extern const unsigned fe_bandwidth_name[8];
+extern const char *dvb_v5_name[46];
extern const void *dvbv5_attr_names[];
[POLARIZATION_R] = "RIGHT",
};
+#define CHANNEL "CHANNEL"
+
+static int fill_entry(struct dvb_entry *entry, int n_prop,
+ char *key, char *value)
+{
+ int i, j, len;
+ int is_video = 0, is_audio = 0;
+ uint16_t *pid = NULL;
+ char *p;
+
+ for (i = 0; i < ARRAY_SIZE(dvb_v5_name); i++) {
+ if (!dvb_v5_name[i])
+ continue;
+ if (!strcasecmp(key, dvb_v5_name[i]))
+ break;
+ }
+
+ /* Handle the DVBv5 DTV_foo properties */
+ if (i < ARRAY_SIZE(dvb_v5_name)) {
+ const char * const *attr_name = dvbv5_attr_names[i];
+
+ entry->props[n_prop].cmd = i;
+ if (!attr_name || !*attr_name)
+ entry->props[n_prop].u.data = atol(value);
+ else {
+ for (j = 0; !attr_name[j]; j++)
+ if (!strcasecmp(value, attr_name[j]))
+ break;
+ if (!attr_name[j])
+ return -2;
+ entry->props[n_prop].u.data = j;
+ }
+ return 0;
+ }
+
+ /* Handle the other properties */
+
+ if (!strcasecmp(key, "SERVICE_ID")) {
+ entry->service_id = atol(value);
+ return 0;
+ }
+
+ if (!strcasecmp(key, "VIDEO_PID"))
+ is_video = 1;
+ else if (!strcasecmp(key, "AUDIO_PID"))
+ is_audio = 1;
+ else if (!strcasecmp(key, "POLARIZATION")) {
+ entry->service_id = atol(value);
+ for (j = 0; ARRAY_SIZE(pol_name); j++)
+ if (!strcasecmp(value, pol_name[j]))
+ break;
+ if (j == ARRAY_SIZE(pol_name))
+ return -2;
+ entry->pol = j;
+ return 0;
+ }
+
+ if (!is_video && !is_audio)
+ return -1;
+
+ /* Video and audio may have multiple values */
+
+ len = 0;
+
+ p = strtok(value," \t");
+ if (!p)
+ return -2;
+ while (p) {
+ pid = realloc(pid, (len + 1) * sizeof (*pid));
+ pid[len] = atol(p);
+ p = strtok(NULL, " \t\n");
+ len++;
+ }
+
+ if (is_video)
+ entry->video_pid = pid;
+ else
+ entry->audio_pid = pid;
+
+ return 0;
+}
+
+
+struct dvb_file *read_dvb_file(const char *fname)
+{
+ char *buf = NULL, *p, *key, *value;
+ size_t size = 0;
+ int len = 0;
+ int line = 0, n_prop = 0, rc;
+ struct dvb_file *dvb_file;
+ FILE *fd;
+ struct dvb_entry *entry = NULL;
+ char err_msg[80];
+
+ dvb_file = calloc(sizeof(*dvb_file), 1);
+ if (!dvb_file) {
+ perror("Allocating memory for dvb_file");
+ return NULL;
+ }
+
+ fd = fopen(fname, "r");
+ if (!fd) {
+ perror(fname);
+ return NULL;
+ }
+
+ do {
+ len = getline(&buf, &size, fd);
+ if (len <= 0)
+ break;
+ line++;
+ p = buf;
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p == '\n' || *p == '#' || *p == '\a' || *p == '\0')
+ continue;
+
+ if (*p == '[') {
+ /* NEW Entry */
+ if (!entry) {
+ dvb_file->first_entry = calloc(sizeof(*entry), 1);
+ entry = dvb_file->first_entry;
+ } else {
+ entry->next = calloc(sizeof(*entry), 1);
+ entry = entry->next;
+ }
+ n_prop = 0;
+ p++;
+ p = strtok(p, "]");
+ if (!p) {
+ sprintf(err_msg, "Missing channel group");
+ goto error;
+ }
+ if (!strcasecmp(p, CHANNEL))
+ p += strlen(CHANNEL);
+ while (*p == ' ' || *p == '\t')
+ p++;
+ if (*p) {
+ entry->channel = calloc(strlen(p) + 1, 1);
+ strcpy(entry->channel, p);
+printf("channel %s", entry->channel);
+ }
+ } else {
+ if (!entry) {
+ sprintf(err_msg, "key/value without a channel group");
+ goto error;
+ }
+ key = strtok(p, "=");
+ if (!key) {
+ sprintf(err_msg, "missing key");
+ goto error;
+ }
+ p = &key[strlen(key) - 1];
+ while (*p == ' ' || *p == '\t')
+ p--;
+ *p = 0;
+ value = strtok(NULL, "\n");
+ if (!value) {
+ sprintf(err_msg, "missing value");
+ goto error;
+ }
+ while (*value == ' ' || *value == '\t')
+ value++;
+
+ rc = fill_entry(entry, n_prop, key, value);
+ if (rc == -2) {
+ sprintf(err_msg, "value %s is invalid for %s",
+ value, key);
+ goto error;
+ } else if (rc == -2) {
+ sprintf(err_msg, "key %s is unknown", key);
+ goto error;
+ }
+ n_prop++;
+ }
+ } while (1);
+ fclose(fd);
+ return dvb_file;
+
+error:
+ fprintf (stderr, "ERROR %s while parsing line %d of %s\n",
+ err_msg, line, fname);
+ dvb_file_free(dvb_file);
+ fclose(fd);
+ return NULL;
+};
+
int write_dvb_file(const char *fname, struct dvb_file *dvb_file)
{
FILE *fp;
uint32_t delsys,
const struct parse_struct *formats);
+
+struct dvb_file *read_dvb_file(const char *fname);
+
int write_dvb_file(const char *fname, struct dvb_file *dvb_file);
int store_dvb_channel(struct dvb_file **dvb_file,
struct dvb_v5_fe_parms *parms,
struct dvb_descriptors *dvb_desc,
int get_detected);
-
const void *dvbv5_attr_names[] = {
[0 ...DTV_MAX_COMMAND ] = NULL,
[DTV_CODE_RATE_HP] = fe_code_rate_name,
- [DTV_CODE_RATE_LP] = fe_code_rate_name,
+ [DTV_CODE_RATE_LP] = fe_code_rate_name,
[DTV_INNER_FEC] = fe_code_rate_name,
[DTV_ISDBT_LAYERA_FEC] = fe_code_rate_name,
[DTV_ISDBT_LAYERB_FEC] = fe_code_rate_name,
[DTV_PILOT] = fe_pilot_name,
[DTV_ROLLOFF] = fe_rolloff_name,
[DTV_DELIVERY_SYSTEM] = delivery_system_name,
-};
\ No newline at end of file
+};
{ FE_TIMEDOUT, "TIMEDOUT" },
};
-const char *fe_code_rate_name[12] = {
+const char *fe_code_rate_name[13] = {
[FEC_1_2] = "1/2",
[FEC_2_3] = "2/3",
[FEC_3_4] = "3/4",
[FEC_9_10] = "9/10",
[FEC_AUTO] = "AUTO",
[FEC_NONE] = "NONE",
+ [12] = NULL,
};
-const char *fe_modulation_name[13] = {
+const char *fe_modulation_name[14] = {
[APSK_16] = "APSK/16",
[APSK_32] = "APSK/32",
[DQPSK] = "DQPSK",
[QPSK] = "QPSK",
[VSB_8] = "VSB/8",
[VSB_16] = "VSB/16",
+ [13] = NULL,
};
-const char *fe_transmission_mode_name[7] = {
+const char *fe_transmission_mode_name[8] = {
[TRANSMISSION_MODE_1K] = "1K",
[TRANSMISSION_MODE_2K] = "2K",
[TRANSMISSION_MODE_4K] = "4K",
[TRANSMISSION_MODE_16K] = "16K",
[TRANSMISSION_MODE_32K] = "32K",
[TRANSMISSION_MODE_AUTO] = "AUTO",
+ [7] = NULL,
};
-const unsigned fe_bandwidth_name[7] = {
+const unsigned fe_bandwidth_name[8] = {
[BANDWIDTH_1_712_MHZ] = 1712000,
[BANDWIDTH_5_MHZ] = 5000000,
[BANDWIDTH_6_MHZ] = 6000000,
[BANDWIDTH_8_MHZ] = 8000000,
[BANDWIDTH_10_MHZ] = 10000000,
[BANDWIDTH_AUTO] = 0,
+ [7] = 0,
};
-const char *fe_guard_interval_name[8] = {
+const char *fe_guard_interval_name[9] = {
[GUARD_INTERVAL_1_4] = "1/4",
[GUARD_INTERVAL_1_8] = "1/8",
[GUARD_INTERVAL_1_16] = "1/16",
[GUARD_INTERVAL_19_128] = "19/128",
[GUARD_INTERVAL_19_256] = "19/256",
[GUARD_INTERVAL_AUTO] = "AUTO",
+ [8] = NULL,
};
-const char *fe_hierarchy_name[5] = {
+const char *fe_hierarchy_name[6] = {
[HIERARCHY_1] = "1",
[HIERARCHY_2] = "2",
[HIERARCHY_4] = "4",
[HIERARCHY_AUTO] = "AUTO",
[HIERARCHY_NONE] = "NONE",
+ [5] = NULL,
};
-const char *fe_voltage_name[3] = {
+const char *fe_voltage_name[4] = {
[SEC_VOLTAGE_13] = "13",
[SEC_VOLTAGE_18] = "18",
[SEC_VOLTAGE_OFF] = "OFF",
+ [3] = NULL,
};
-const char *fe_tone_name[2] = {
+const char *fe_tone_name[3] = {
[SEC_TONE_OFF] = "OFF",
[SEC_TONE_ON] = "ON",
+ [2] = NULL,
};
-const char *fe_inversion_name[3] = {
+const char *fe_inversion_name[4] = {
[INVERSION_AUTO] = "AUTO",
[INVERSION_OFF] = "OFF",
[INVERSION_ON] = "ON",
+ [3] = NULL,
};
-const char *fe_pilot_name[3] = {
+const char *fe_pilot_name[4] = {
[PILOT_AUTO] = "AUTO",
[PILOT_OFF] = "OFF",
[PILOT_ON] = "ON",
+ [3] = NULL,
};
-const char *fe_rolloff_name[4] = {
+const char *fe_rolloff_name[5] = {
[ROLLOFF_20] = "20",
[ROLLOFF_25] = "25",
[ROLLOFF_35] = "35",
[ROLLOFF_AUTO] = "AUTO",
+ [4] = NULL,
};
-const char *dvb_v5_name[45] = {
+const char *dvb_v5_name[46] = {
[DTV_API_VERSION] = "API_VERSION",
[DTV_BANDWIDTH_HZ] = "BANDWIDTH_HZ",
[DTV_CLEAR] = "CLEAR",
[DTV_TUNE] = "TUNE",
[DTV_UNDEFINED] = "UNDEFINED",
[DTV_VOLTAGE] = "VOLTAGE",
+ [45] = NULL,
};
-const char *delivery_system_name[19] = {
+const char *delivery_system_name[20] = {
[SYS_ATSC] = "ATSC",
[SYS_ATSCMH] = "ATSCMH",
[SYS_CMMB] = "CMMB",
[SYS_ISDBT] = "ISDBT",
[SYS_TURBO] = "TURBO",
[SYS_UNDEFINED] = "UNDEFINED",
+ [19] = NULL,
};
#endif
fprintf(stderr, " (%s)\n", strerror(errno)); \
} while (0)
-static int parse(const char *fname, const char *channel,
+static int parse(const char *fname, int old_format, const char *channel,
struct dvb_v5_fe_parms *parms,
uint32_t *vpid, uint32_t *apid, uint32_t *sid)
{
return -1;
}
- dvb_file = parse_format_oneline(fname, ":", sys, zap_formats);
+ if (old_format)
+ dvb_file = parse_format_oneline(fname, ":", sys, zap_formats);
+ else
+ dvb_file = read_dvb_file(fname);
if (!dvb_file)
return -2;
" -F : set up frontend only, don't touch demux\n"
" -t number : timeout (seconds)\n"
" -o file : output filename (use -o - for stdout)\n"
+ " -O : Channel configuration is using the old format\n"
" -h -? : display this help and exit\n";
int main(int argc, char **argv)
int opt;
int record = 0;
int frontend_only = 0;
+ int old_format = 0;
char *filename = NULL;
int human_readable = 0, rec_psi = 0;
struct dvb_v5_fe_parms *parms;
- while ((opt = getopt(argc, argv, "H?hrpxRsFSn:a:f:d:c:t:o:")) != -1) {
+ while ((opt = getopt(argc, argv, "H?hrpxRsFSn:a:f:d:c:t:o:O")) != -1) {
switch (opt) {
case 'a':
adapter = strtoul(optarg, NULL, 0);
case 't':
timeout = strtoul(optarg, NULL, 0);
break;
+ case 'O':
+ old_format++;
+ break;
case 'o':
filename = strdup(optarg);
record = 1;
parms = dvb_fe_open(adapter, frontend, !silent, 0);
- if (parse(confname, channel, parms, &vpid, &apid, &sid))
+ if (parse(confname, old_format, channel, parms, &vpid, &apid, &sid))
return -1;
if (setup_frontend(parms) < 0)
printf OUT "struct %s {\n\t\%s idx;\n\tchar *name;\n} %s[%i] = {\n",
$name, $type, $name, $size;
} else {
- printf OUT "const %s%s[%i] = {\n", $type, $name, $size;
+ printf OUT "const %s%s[%i] = {\n", $type, $name, $size + 1;
}
foreach my $i (sort keys %$struct) {
}
}
}
+
+ if (!$bitmap) {
+ printf OUT "\t[%s] = ", $size;
+ if ($type eq "char *") {
+ printf OUT "NULL,\n";
+ } else {
+ printf OUT "0,\n";
+ }
+ }
+
+
printf OUT "};\n\n";
}