[linux-dvb] Johannes' idea of simple zap (szap)

Manu Abraham manu at kromtek.com
Sun Jun 12 22:48:16 CEST 2005


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 at kromtek.com)

	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 at kromtek.com)

	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


More information about the linux-dvb mailing list