diff options
135 files changed, 12823 insertions, 0 deletions
| diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..e0eadcf --- /dev/null +++ b/Makefile @@ -0,0 +1,28 @@ +# Makefile for linuxtv.org dvb-apps + +VERSION := 1.1.0 +PACKAGE := linuxtv-dvb-apps-$(VERSION) +CVSROOT := $(shell cat CVS/Root) +RELEASE_TAG := LINUXTV-DVB-$(subst .,_,$(subst -,_,$(VERSION))) + +all: + +release dist: +	rm -rf release-tmp $(PACKAGE).tar.gz +	mkdir release-tmp +	( cd release-tmp; cvs -d$(CVSROOT) export -r$(RELEASE_TAG) -d$(PACKAGE) dvb-apps ) +	find release-tmp -name .cvsignore | xargs rm -v +	( cd release-tmp; tar cjf ../$(PACKAGE).tar.bz2 $(PACKAGE) ) +	rm -rf release-tmp +	@echo +	@echo -------------------------------------------------------------------------------- +	@echo +	@echo "dist package: ./$(PACKAGE).tar.bz2" +	@echo +	@echo -------------------------------------------------------------------------------- +	@echo + +%:: +#	$(MAKE) -C libdvb2 $(MAKECMDGOALS) +	$(MAKE) -C util $(MAKECMDGOALS) +	$(MAKE) -C test $(MAKECMDGOALS) @@ -0,0 +1,21 @@ +linuxtv-dvb-apps-1.1.0 +====================== + +Linux DVB API test/demo applications and utilities. + +You find a README in each subdirectory explaining what the code there does. +For beginners utils/szap/ and utils/scan/ are probably most useful. + +For convenience, dvb-apps contains a copy of the DVB API include +files as they are contained in the linuxtv-dvb-1.1.0 realease +and the 2.6.x Linux kernel. However, since the DVB API hasn't changed, +the apps will still work with the old "DVB" drivers, should you decide not +to use linuxtv-dvb-1.1.0 (or the dvb-kernel CVS). + + +Historical note: +The apps have been copied from the "DVB" CVS tree, which means that +the stuff in "DVB" is now unmaintained and out of date. + + +Johannes Stezenbach <js@convergence.de> @@ -0,0 +1 @@ +- create libdvb2, possibly merging util/lib/* diff --git a/include/linux/dvb/audio.h b/include/linux/dvb/audio.h new file mode 100644 index 0000000..58956c3 --- /dev/null +++ b/include/linux/dvb/audio.h @@ -0,0 +1,125 @@ +/*  + * audio.h + * + * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> +                      for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Lesser Public License + * as published by the Free Software Foundation; either version 2.1 + * 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#ifndef _DVBAUDIO_H_ +#define _DVBAUDIO_H_ + +#ifdef __KERNEL__ +#include <linux/types.h> +#else +#include <stdint.h> +#endif + + +typedef enum { +        AUDIO_SOURCE_DEMUX, /* Select the demux as the main source */  +	AUDIO_SOURCE_MEMORY /* Select internal memory as the main source */  +} audio_stream_source_t; + + +typedef enum {  +	AUDIO_STOPPED,      /* Device is stopped */  +        AUDIO_PLAYING,      /* Device is currently playing */  +	AUDIO_PAUSED        /* Device is paused */  +} audio_play_state_t; + + +typedef enum { +        AUDIO_STEREO, +        AUDIO_MONO_LEFT,  +	AUDIO_MONO_RIGHT  +} audio_channel_select_t; + + +typedef struct audio_mixer {  +        unsigned int volume_left; +        unsigned int volume_right; +  // what else do we need? bass, pass-through, ... +} audio_mixer_t; + + +typedef struct audio_status {  +        int                    AV_sync_state;  /* sync audio and video? */ +        int                    mute_state;     /* audio is muted */  +        audio_play_state_t     play_state;     /* current playback state */ +        audio_stream_source_t  stream_source;  /* current stream source */ +        audio_channel_select_t channel_select; /* currently selected channel */ +        int                    bypass_mode;    /* pass on audio data to */ +	audio_mixer_t	       mixer_state;    /* current mixer state */ +} audio_status_t;                              /* separate decoder hardware */ + + +typedef +struct audio_karaoke{  /* if Vocal1 or Vocal2 are non-zero, they get mixed  */ +	int vocal1;    /* into left and right t at 70% each */ +	int vocal2;    /* if both, Vocal1 and Vocal2 are non-zero, Vocal1 gets*/ +	int melody;    /* mixed into the left channel and */ +                       /* Vocal2 into the right channel at 100% each. */ +                       /* if Melody is non-zero, the melody channel gets mixed*/ +} audio_karaoke_t;     /* into left and right  */ + + +typedef uint16_t audio_attributes_t; +/*   bits: descr. */ +/*   15-13 audio coding mode (0=ac3, 2=mpeg1, 3=mpeg2ext, 4=LPCM, 6=DTS, */ +/*   12    multichannel extension */ +/*   11-10 audio type (0=not spec, 1=language included) */ +/*    9- 8 audio application mode (0=not spec, 1=karaoke, 2=surround) */ +/*    7- 6 Quantization / DRC (mpeg audio: 1=DRC exists)(lpcm: 0=16bit,  */ +/*    5- 4 Sample frequency fs (0=48kHz, 1=96kHz) */ +/*    2- 0 number of audio channels (n+1 channels) */ +  + +/* for GET_CAPABILITIES and SET_FORMAT, the latter should only set one bit */ +#define AUDIO_CAP_DTS    1 +#define AUDIO_CAP_LPCM   2 +#define AUDIO_CAP_MP1    4 +#define AUDIO_CAP_MP2    8 +#define AUDIO_CAP_MP3   16 +#define AUDIO_CAP_AAC   32 +#define AUDIO_CAP_OGG   64 +#define AUDIO_CAP_SDDS 128 +#define AUDIO_CAP_AC3  256 + +#define AUDIO_STOP                 _IO('o', 1)  +#define AUDIO_PLAY                 _IO('o', 2) +#define AUDIO_PAUSE                _IO('o', 3) +#define AUDIO_CONTINUE             _IO('o', 4) +#define AUDIO_SELECT_SOURCE        _IO('o', 5) +#define AUDIO_SET_MUTE             _IO('o', 6) +#define AUDIO_SET_AV_SYNC          _IO('o', 7) +#define AUDIO_SET_BYPASS_MODE      _IO('o', 8) +#define AUDIO_CHANNEL_SELECT       _IO('o', 9) +#define AUDIO_GET_STATUS           _IOR('o', 10, audio_status_t) + +#define AUDIO_GET_CAPABILITIES     _IOR('o', 11, unsigned int) +#define AUDIO_CLEAR_BUFFER         _IO('o',  12) +#define AUDIO_SET_ID               _IO('o', 13) +#define AUDIO_SET_MIXER            _IOW('o', 14, audio_mixer_t) +#define AUDIO_SET_STREAMTYPE       _IO('o', 15) +#define AUDIO_SET_EXT_ID           _IO('o', 16) +#define AUDIO_SET_ATTRIBUTES       _IOW('o', 17, audio_attributes_t) +#define AUDIO_SET_KARAOKE          _IOW('o', 18, audio_karaoke_t) + +#endif /* _DVBAUDIO_H_ */ + diff --git a/include/linux/dvb/ca.h b/include/linux/dvb/ca.h new file mode 100644 index 0000000..026e5c3 --- /dev/null +++ b/include/linux/dvb/ca.h @@ -0,0 +1,91 @@ +/*  + * ca.h + * + * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> +                      for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Lesser Public License + * as published by the Free Software Foundation; either version 2.1 + * 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#ifndef _DVBCA_H_ +#define _DVBCA_H_ + +/* slot interface types and info */ + +typedef struct ca_slot_info { +        int num;               /* slot number */ + +        int type;              /* CA interface this slot supports */ +#define CA_CI            1     /* CI high level interface */ +#define CA_CI_LINK       2     /* CI link layer level interface */ +#define CA_CI_PHYS       4     /* CI physical layer level interface */ +#define CA_DESCR         8     /* built-in descrambler */ +#define CA_SC          128     /* simple smart card interface */ + +        unsigned int flags; +#define CA_CI_MODULE_PRESENT 1 /* module (or card) inserted */ +#define CA_CI_MODULE_READY   2 +} ca_slot_info_t; + + +/* descrambler types and info */ + +typedef struct ca_descr_info { +        unsigned int num;          /* number of available descramblers (keys) */ +        unsigned int type;         /* type of supported scrambling system */ +#define CA_ECD           1 +#define CA_NDS           2 +#define CA_DSS           4 +} ca_descr_info_t; + +typedef struct ca_caps { +        unsigned int slot_num;     /* total number of CA card and module slots */ +        unsigned int slot_type;    /* OR of all supported types */ +        unsigned int descr_num;    /* total number of descrambler slots (keys) */ +        unsigned int descr_type;   /* OR of all supported types */ +} ca_caps_t; + +/* a message to/from a CI-CAM */ +typedef struct ca_msg { +        unsigned int index; +        unsigned int type; +        unsigned int length; +        unsigned char msg[256]; +} ca_msg_t; + +typedef struct ca_descr { +        unsigned int index; +        unsigned int parity;	/* 0 == even, 1 == odd */ +        unsigned char cw[8]; +} ca_descr_t; + +typedef struct ca_pid { +        unsigned int pid; +        int index;		/* -1 == disable*/ +} ca_pid_t; + +#define CA_RESET          _IO('o', 128) +#define CA_GET_CAP        _IOR('o', 129, ca_caps_t) +#define CA_GET_SLOT_INFO  _IOR('o', 130, ca_slot_info_t) +#define CA_GET_DESCR_INFO _IOR('o', 131, ca_descr_info_t) +#define CA_GET_MSG        _IOR('o', 132, ca_msg_t) +#define CA_SEND_MSG       _IOW('o', 133, ca_msg_t) +#define CA_SET_DESCR      _IOW('o', 134, ca_descr_t) +#define CA_SET_PID        _IOW('o', 135, ca_pid_t) + +#endif + diff --git a/include/linux/dvb/dmx.h b/include/linux/dvb/dmx.h new file mode 100644 index 0000000..62e6217 --- /dev/null +++ b/include/linux/dvb/dmx.h @@ -0,0 +1,181 @@ +/*  + * dmx.h + * + * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de> + *                  & Ralph  Metzler <ralph@convergence.de> +                      for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#ifndef _DVBDMX_H_ +#define _DVBDMX_H_ + +#include <asm/types.h> +#ifdef __KERNEL__ +#include <linux/time.h> +#else +#include <time.h> +#endif + + +#define DMX_FILTER_SIZE 16 + +typedef enum +{ +	DMX_OUT_DECODER, /* Streaming directly to decoder. */ +	DMX_OUT_TAP,     /* Output going to a memory buffer */ +	                 /* (to be retrieved via the read command).*/ +	DMX_OUT_TS_TAP   /* Output multiplexed into a new TS  */ +	                 /* (to be retrieved by reading from the */ +	                 /* logical DVR device).                 */ +} dmx_output_t; + + +typedef enum +{ +	DMX_IN_FRONTEND, /* Input from a front-end device.  */ +	DMX_IN_DVR       /* Input from the logical DVR device.  */ +} dmx_input_t; + + +typedef enum +{ +        DMX_PES_AUDIO0, +	DMX_PES_VIDEO0, +	DMX_PES_TELETEXT0, +	DMX_PES_SUBTITLE0, +	DMX_PES_PCR0, + +        DMX_PES_AUDIO1, +	DMX_PES_VIDEO1, +	DMX_PES_TELETEXT1, +	DMX_PES_SUBTITLE1, +	DMX_PES_PCR1, + +        DMX_PES_AUDIO2, +	DMX_PES_VIDEO2, +	DMX_PES_TELETEXT2, +	DMX_PES_SUBTITLE2, +	DMX_PES_PCR2, + +        DMX_PES_AUDIO3, +	DMX_PES_VIDEO3, +	DMX_PES_TELETEXT3, +	DMX_PES_SUBTITLE3, +	DMX_PES_PCR3, + +	DMX_PES_OTHER +} dmx_pes_type_t; + +#define DMX_PES_AUDIO    DMX_PES_AUDIO0 +#define DMX_PES_VIDEO    DMX_PES_VIDEO0 +#define DMX_PES_TELETEXT DMX_PES_TELETEXT0 +#define DMX_PES_SUBTITLE DMX_PES_SUBTITLE0 +#define DMX_PES_PCR      DMX_PES_PCR0 + + +typedef enum +{ +        DMX_SCRAMBLING_EV, +        DMX_FRONTEND_EV +} dmx_event_t; + + +typedef enum +{ +	DMX_SCRAMBLING_OFF, +	DMX_SCRAMBLING_ON +} dmx_scrambling_status_t; + + +typedef struct dmx_filter +{ +	__u8  filter[DMX_FILTER_SIZE]; +	__u8  mask[DMX_FILTER_SIZE]; +	__u8  mode[DMX_FILTER_SIZE]; +} dmx_filter_t; + + +struct dmx_sct_filter_params +{ +	__u16            pid; +	dmx_filter_t   filter; +	__u32            timeout; +	__u32            flags; +#define DMX_CHECK_CRC       1 +#define DMX_ONESHOT         2 +#define DMX_IMMEDIATE_START 4 +#define DMX_KERNEL_CLIENT   0x8000 +}; + + +struct dmx_pes_filter_params +{ +	__u16            pid; +	dmx_input_t    input; +	dmx_output_t   output; +	dmx_pes_type_t pes_type; +	__u32            flags; +}; + + +struct dmx_event +{ +	dmx_event_t         event; +	time_t              timeStamp; +	union +	{ +		dmx_scrambling_status_t scrambling; +	} u; +}; + +typedef struct dmx_caps { +	__u32 caps; +	int num_decoders;  +} dmx_caps_t; + +typedef enum { +	DMX_SOURCE_FRONT0 = 0, +	DMX_SOURCE_FRONT1, +	DMX_SOURCE_FRONT2, +	DMX_SOURCE_FRONT3, +	DMX_SOURCE_DVR0   = 16, +	DMX_SOURCE_DVR1, +	DMX_SOURCE_DVR2, +	DMX_SOURCE_DVR3 +} dmx_source_t; + +struct dmx_stc { +	unsigned int num;	/* input : which STC? 0..N */ +	unsigned int base;	/* output: divisor for stc to get 90 kHz clock */ +	__u64 stc;		/* output: stc in 'base'*90 kHz units */ +}; + + +#define DMX_START                _IO('o', 41)  +#define DMX_STOP                 _IO('o', 42) +#define DMX_SET_FILTER           _IOW('o', 43, struct dmx_sct_filter_params) +#define DMX_SET_PES_FILTER       _IOW('o', 44, struct dmx_pes_filter_params) +#define DMX_SET_BUFFER_SIZE      _IO('o', 45) +#define DMX_GET_EVENT            _IOR('o', 46, struct dmx_event) +#define DMX_GET_PES_PIDS         _IOR('o', 47, __u16[5]) +#define DMX_GET_CAPS             _IOR('o', 48, dmx_caps_t) +#define DMX_SET_SOURCE           _IOW('o', 49, dmx_source_t) +#define DMX_GET_STC              _IOWR('o', 50, struct dmx_stc) + +#endif /*_DVBDMX_H_*/ + diff --git a/include/linux/dvb/frontend.h b/include/linux/dvb/frontend.h new file mode 100644 index 0000000..3fa118e --- /dev/null +++ b/include/linux/dvb/frontend.h @@ -0,0 +1,260 @@ +/* + * frontend.h + * + * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de> + *                    Ralph  Metzler <ralph@convergence.de> + *                    Holger Waechtler <holger@convergence.de> + *                    Andre Draszik <ad@convergence.de> + *                    for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#ifndef _DVBFRONTEND_H_ +#define _DVBFRONTEND_H_ + +#include <asm/types.h> + + +typedef enum fe_type { +        FE_QPSK, +        FE_QAM, +        FE_OFDM +} fe_type_t; + + +typedef enum fe_caps { +	FE_IS_STUPID                  = 0, +	FE_CAN_INVERSION_AUTO         = 0x1, +	FE_CAN_FEC_1_2                = 0x2, +	FE_CAN_FEC_2_3                = 0x4, +	FE_CAN_FEC_3_4                = 0x8, +	FE_CAN_FEC_4_5                = 0x10, +	FE_CAN_FEC_5_6                = 0x20, +	FE_CAN_FEC_6_7                = 0x40, +	FE_CAN_FEC_7_8                = 0x80, +	FE_CAN_FEC_8_9                = 0x100, +	FE_CAN_FEC_AUTO               = 0x200, +	FE_CAN_QPSK                   = 0x400, +	FE_CAN_QAM_16                 = 0x800, +	FE_CAN_QAM_32                 = 0x1000, +	FE_CAN_QAM_64                 = 0x2000, +	FE_CAN_QAM_128                = 0x4000, +	FE_CAN_QAM_256                = 0x8000, +	FE_CAN_QAM_AUTO               = 0x10000, +	FE_CAN_TRANSMISSION_MODE_AUTO = 0x20000, +	FE_CAN_BANDWIDTH_AUTO         = 0x40000, +	FE_CAN_GUARD_INTERVAL_AUTO    = 0x80000, +	FE_CAN_HIERARCHY_AUTO         = 0x100000, +	FE_CAN_RECOVER                = 0x20000000, +	FE_CAN_CLEAN_SETUP            = 0x40000000, +	FE_CAN_MUTE_TS                = 0x80000000 +} fe_caps_t; + + +struct dvb_frontend_info { +	char       name[128]; +        fe_type_t  type; +        __u32      frequency_min; +        __u32      frequency_max; +	__u32      frequency_stepsize; +	__u32      frequency_tolerance; +	__u32      symbol_rate_min; +        __u32      symbol_rate_max; +	__u32      symbol_rate_tolerance;     /* ppm */ +	__u32      notifier_delay;            /* ms */ +	fe_caps_t  caps; +}; + + +/** + *  Check out the DiSEqC bus spec available on http://www.eutelsat.org/ for + *  the meaning of this struct... + */ +struct dvb_diseqc_master_cmd { +        __u8 msg [6];        /*  { framing, address, command, data [3] } */ +        __u8 msg_len;        /*  valid values are 3...6  */ +}; + + +struct dvb_diseqc_slave_reply { +	__u8 msg [4];        /*  { framing, data [3] } */ +	__u8 msg_len;        /*  valid values are 0...4, 0 means no msg  */ +	int  timeout;        /*  return from ioctl after timeout ms with */ +};                           /*  errorcode when no message was received  */ + + +typedef enum fe_sec_voltage { +        SEC_VOLTAGE_13, +        SEC_VOLTAGE_18, +	SEC_VOLTAGE_OFF +} fe_sec_voltage_t; + + +typedef enum fe_sec_tone_mode { +        SEC_TONE_ON, +        SEC_TONE_OFF +} fe_sec_tone_mode_t; + + +typedef enum fe_sec_mini_cmd { +        SEC_MINI_A, +        SEC_MINI_B +} fe_sec_mini_cmd_t; + + +typedef enum fe_status { +	FE_HAS_SIGNAL     = 0x01,   /*  found something above the noise level */ +	FE_HAS_CARRIER    = 0x02,   /*  found a DVB signal  */ +	FE_HAS_VITERBI    = 0x04,   /*  FEC is stable  */ +	FE_HAS_SYNC       = 0x08,   /*  found sync bytes  */ +	FE_HAS_LOCK       = 0x10,   /*  everything's working... */ +	FE_TIMEDOUT       = 0x20,   /*  no lock within the last ~2 seconds */ +	FE_REINIT         = 0x40    /*  frontend was reinitialized,  */ +} fe_status_t;                      /*  application is recommended to reset */ +                                    /*  DiSEqC, tone and parameters */ + +typedef enum fe_spectral_inversion { +        INVERSION_OFF, +        INVERSION_ON, +        INVERSION_AUTO +} fe_spectral_inversion_t; + + +typedef enum fe_code_rate { +        FEC_NONE = 0, +        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 +} fe_code_rate_t; + + +typedef enum fe_modulation { +        QPSK, +        QAM_16, +        QAM_32, +        QAM_64, +        QAM_128, +        QAM_256, +	QAM_AUTO +} fe_modulation_t; + + +typedef enum fe_transmit_mode { +	TRANSMISSION_MODE_2K, +	TRANSMISSION_MODE_8K, +	TRANSMISSION_MODE_AUTO +} fe_transmit_mode_t; + +typedef enum fe_bandwidth { +	BANDWIDTH_8_MHZ, +	BANDWIDTH_7_MHZ, +	BANDWIDTH_6_MHZ, +	BANDWIDTH_AUTO +} fe_bandwidth_t; + + +typedef enum fe_guard_interval { +	GUARD_INTERVAL_1_32, +	GUARD_INTERVAL_1_16, +	GUARD_INTERVAL_1_8, +	GUARD_INTERVAL_1_4, +	GUARD_INTERVAL_AUTO +} fe_guard_interval_t; + + +typedef enum fe_hierarchy { +	HIERARCHY_NONE, +	HIERARCHY_1, +	HIERARCHY_2, +	HIERARCHY_4, +	HIERARCHY_AUTO +} fe_hierarchy_t; + + +struct dvb_qpsk_parameters { +        __u32           symbol_rate;  /* symbol rate in Symbols per second */ +        fe_code_rate_t  fec_inner;    /* forward error correction (see above) */ +}; + + +struct dvb_qam_parameters { +        __u32            symbol_rate; /* symbol rate in Symbols per second */ +        fe_code_rate_t   fec_inner;   /* forward error correction (see above) */ +        fe_modulation_t  modulation;  /* modulation type (see above) */ +}; + + +struct dvb_ofdm_parameters { +        fe_bandwidth_t      bandwidth; +        fe_code_rate_t      code_rate_HP;  /* high priority stream code rate */ +        fe_code_rate_t      code_rate_LP;  /* low priority stream code rate */ +        fe_modulation_t     constellation; /* modulation type (see above) */ +        fe_transmit_mode_t  transmission_mode; +        fe_guard_interval_t guard_interval; +        fe_hierarchy_t      hierarchy_information; +}; + + +struct dvb_frontend_parameters { +        __u32 frequency;     /* (absolute) frequency in Hz for QAM/OFDM */ +                             /* intermediate frequency in kHz for QPSK */ +	fe_spectral_inversion_t inversion; +	union { +		struct dvb_qpsk_parameters qpsk; +		struct dvb_qam_parameters  qam; +		struct dvb_ofdm_parameters ofdm; +	} u; +}; + + +struct dvb_frontend_event { +	fe_status_t status; +	struct dvb_frontend_parameters parameters; +}; + + + +#define FE_GET_INFO                _IOR('o', 61, struct dvb_frontend_info) + +#define FE_DISEQC_RESET_OVERLOAD   _IO('o', 62) +#define FE_DISEQC_SEND_MASTER_CMD  _IOW('o', 63, struct dvb_diseqc_master_cmd) +#define FE_DISEQC_RECV_SLAVE_REPLY _IOR('o', 64, struct dvb_diseqc_slave_reply) +#define FE_DISEQC_SEND_BURST       _IO('o', 65)  /* fe_sec_mini_cmd_t */ + +#define FE_SET_TONE                _IO('o', 66)  /* fe_sec_tone_mode_t */ +#define FE_SET_VOLTAGE             _IO('o', 67)  /* fe_sec_voltage_t */ +#define FE_ENABLE_HIGH_LNB_VOLTAGE _IO('o', 68)  /* int */ + +#define FE_READ_STATUS             _IOR('o', 69, fe_status_t) +#define FE_READ_BER                _IOR('o', 70, __u32) +#define FE_READ_SIGNAL_STRENGTH    _IOR('o', 71, __u16) +#define FE_READ_SNR                _IOR('o', 72, __u16) +#define FE_READ_UNCORRECTED_BLOCKS _IOR('o', 73, __u32) + +#define FE_SET_FRONTEND            _IOW('o', 76, struct dvb_frontend_parameters) +#define FE_GET_FRONTEND            _IOR('o', 77, struct dvb_frontend_parameters) +#define FE_GET_EVENT               _IOR('o', 78, struct dvb_frontend_event) + + +#endif /*_DVBFRONTEND_H_*/ + diff --git a/include/linux/dvb/net.h b/include/linux/dvb/net.h new file mode 100644 index 0000000..4b8fa51 --- /dev/null +++ b/include/linux/dvb/net.h @@ -0,0 +1,41 @@ +/*  + * net.h + * + * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de> + *                  & Ralph  Metzler <ralph@convergence.de> +                      for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#ifndef _DVBNET_H_ +#define _DVBNET_H_ + +#include <asm/types.h> + + +struct dvb_net_if { +	__u16 pid; +	__u16 if_num; +}; + + +#define NET_ADD_IF                 _IOWR('o', 52, struct dvb_net_if) +#define NET_REMOVE_IF              _IO('o', 53) +#define NET_GET_IF                 _IOWR('o', 54, struct dvb_net_if) + +#endif /*_DVBNET_H_*/ + diff --git a/include/linux/dvb/osd.h b/include/linux/dvb/osd.h new file mode 100644 index 0000000..0d81439 --- /dev/null +++ b/include/linux/dvb/osd.h @@ -0,0 +1,111 @@ +/*  + * osd.h + * + * Copyright (C) 2001 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> +                      for convergence integrated media GmbH + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Lesser Public License + * as published by the Free Software Foundation; either version 2.1 + * 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#ifndef _DVBOSD_H_ +#define _DVBOSD_H_ + +typedef enum { +  // All functions return -2 on "not open" +  OSD_Close=1,    // () +  // Disables OSD and releases the buffers +  // returns 0 on success +  OSD_Open,       // (x0,y0,x1,y1,BitPerPixel[2/4/8](color&0x0F),mix[0..15](color&0xF0)) +  // Opens OSD with this size and bit depth +  // returns 0 on success, -1 on DRAM allocation error, -2 on "already open" +  OSD_Show,       // () +  // enables OSD mode +  // returns 0 on success +  OSD_Hide,       // () +  // disables OSD mode +  // returns 0 on success +  OSD_Clear,      // () +  // Sets all pixel to color 0 +  // returns 0 on success +  OSD_Fill,       // (color) +  // Sets all pixel to color <col> +  // returns 0 on success +  OSD_SetColor,   // (color,R{x0},G{y0},B{x1},opacity{y1}) +  // set palette entry <num> to <r,g,b>, <mix> and <trans> apply +  // R,G,B: 0..255 +  // R=Red, G=Green, B=Blue +  // opacity=0:      pixel opacity 0% (only video pixel shows) +  // opacity=1..254: pixel opacity as specified in header +  // opacity=255:    pixel opacity 100% (only OSD pixel shows) +  // returns 0 on success, -1 on error +  OSD_SetPalette, // (firstcolor{color},lastcolor{x0},data) +  // Set a number of entries in the palette +  // sets the entries "firstcolor" through "lastcolor" from the array "data" +  // data has 4 byte for each color: +  // R,G,B, and a opacity value: 0->transparent, 1..254->mix, 255->pixel +  OSD_SetTrans,   // (transparency{color}) +  // Sets transparency of mixed pixel (0..15) +  // returns 0 on success +  OSD_SetPixel,   // (x0,y0,color) +  // sets pixel <x>,<y> to color number <col> +  // returns 0 on success, -1 on error +  OSD_GetPixel,   // (x0,y0) +  // returns color number of pixel <x>,<y>,  or -1 +  OSD_SetRow,     // (x0,y0,x1,data) +  // fills pixels x0,y through  x1,y with the content of data[] +  // returns 0 on success, -1 on clipping all pixel (no pixel drawn) +  OSD_SetBlock,   // (x0,y0,x1,y1,increment{color},data) +  // fills pixels x0,y0 through  x1,y1 with the content of data[] +  // inc contains the width of one line in the data block, +  // inc<=0 uses blockwidth as linewidth +  // returns 0 on success, -1 on clipping all pixel +  OSD_FillRow,    // (x0,y0,x1,color) +  // fills pixels x0,y through  x1,y with the color <col> +  // returns 0 on success, -1 on clipping all pixel +  OSD_FillBlock,  // (x0,y0,x1,y1,color) +  // fills pixels x0,y0 through  x1,y1 with the color <col> +  // returns 0 on success, -1 on clipping all pixel +  OSD_Line,       // (x0,y0,x1,y1,color) +  // draw a line from x0,y0 to x1,y1 with the color <col> +  // returns 0 on success +  OSD_Query,      // (x0,y0,x1,y1,xasp{color}}), yasp=11 +  // fills parameters with the picture dimensions and the pixel aspect ratio +  // returns 0 on success +  OSD_Test,       // () +  // draws a test picture. for debugging purposes only +  // returns 0 on success +// TODO: remove "test" in final version +  OSD_Text,       // (x0,y0,size,color,text) +  OSD_SetWindow, //  (x0) set window with number 0<x0<8 as current +  OSD_MoveWindow, //  move current window to (x0, y0)   +} OSD_Command; + +typedef struct osd_cmd_s { +        OSD_Command cmd; +        int x0; +        int y0; +        int x1; +        int y1; +        int color; +        void *data; +} osd_cmd_t; + + +#define OSD_SEND_CMD       _IOW('o', 160, osd_cmd_t) + +#endif + diff --git a/include/linux/dvb/version.h b/include/linux/dvb/version.h new file mode 100644 index 0000000..54e256e --- /dev/null +++ b/include/linux/dvb/version.h @@ -0,0 +1,29 @@ +/* + * version.h + * + * Copyright (C) 2000 Holger Waechtler <holger@convergence.de> + *                    for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#ifndef _DVBVERSION_H_ +#define _DVBVERSION_H_ + +#define DVB_API_VERSION 3 + +#endif /*_DVBVERSION_H_*/ + diff --git a/include/linux/dvb/video.h b/include/linux/dvb/video.h new file mode 100644 index 0000000..a8b6008 --- /dev/null +++ b/include/linux/dvb/video.h @@ -0,0 +1,199 @@ +/*  + * video.h + * + * Copyright (C) 2000 Marcus Metzler <marcus@convergence.de> + *                  & Ralph  Metzler <ralph@convergence.de> +                      for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#ifndef _DVBVIDEO_H_ +#define _DVBVIDEO_H_ + +#ifdef __KERNEL__ +#include <linux/types.h> +#else +#include <stdint.h> +#include <time.h> +#endif + + +typedef enum { +	VIDEO_FORMAT_4_3,     /* Select 4:3 format */ +        VIDEO_FORMAT_16_9,    /* Select 16:9 format. */ +	VIDEO_FORMAT_221_1    /* 2.21:1 */ +} video_format_t; + + +typedef enum { +	 VIDEO_SYSTEM_PAL,  +	 VIDEO_SYSTEM_NTSC,  +	 VIDEO_SYSTEM_PALN,  +	 VIDEO_SYSTEM_PALNc,  +	 VIDEO_SYSTEM_PALM,  +	 VIDEO_SYSTEM_NTSC60,  +	 VIDEO_SYSTEM_PAL60, +	 VIDEO_SYSTEM_PALM60 +} video_system_t; + + +typedef enum {    +        VIDEO_PAN_SCAN,       /* use pan and scan format */ +	VIDEO_LETTER_BOX,     /* use letterbox format */ +	VIDEO_CENTER_CUT_OUT  /* use center cut out format */ +} video_displayformat_t; + +typedef struct { +	int w; +	int h; +	video_format_t aspect_ratio; +} video_size_t; + +typedef enum { +        VIDEO_SOURCE_DEMUX, /* Select the demux as the main source */  +	VIDEO_SOURCE_MEMORY /* If this source is selected, the stream  +			       comes from the user through the write  +			       system call */  +} video_stream_source_t; + + +typedef enum { +	VIDEO_STOPPED, /* Video is stopped */  +        VIDEO_PLAYING, /* Video is currently playing */  +	VIDEO_FREEZED  /* Video is freezed */  +} video_play_state_t;  + + +struct video_event {  +        int32_t type;  +#define VIDEO_EVENT_SIZE_CHANGED 1 +        time_t timestamp; +	union { +	        video_size_t size; +	} u; +}; + + +struct video_status {  +        int                   video_blank;   /* blank video on freeze? */ +        video_play_state_t    play_state;    /* current state of playback */   +        video_stream_source_t stream_source; /* current source (demux/memory) */ +        video_format_t        video_format;  /* current aspect ratio of stream*/ +        video_displayformat_t display_format;/* selected cropping mode */ +}; + + +struct video_still_picture { +        char *iFrame;        /* pointer to a single iframe in memory */ +        int32_t size;  +}; + + +typedef  +struct video_highlight { +	int     active;      /*    1=show highlight, 0=hide highlight */ +	uint8_t contrast1;   /*    7- 4  Pattern pixel contrast */ +                             /*    3- 0  Background pixel contrast */ +	uint8_t contrast2;   /*    7- 4  Emphasis pixel-2 contrast */ +                             /*    3- 0  Emphasis pixel-1 contrast */ +	uint8_t color1;      /*    7- 4  Pattern pixel color */ +                             /*    3- 0  Background pixel color */ +	uint8_t color2;      /*    7- 4  Emphasis pixel-2 color */ +                             /*    3- 0  Emphasis pixel-1 color */ + 	uint32_t ypos;       /*   23-22  auto action mode */ +                             /*   21-12  start y */ +                             /*    9- 0  end y */ +	uint32_t xpos;       /*   23-22  button color number */ +                             /*   21-12  start x */ +                             /*    9- 0  end x */ +} video_highlight_t; + + +typedef struct video_spu { +	int active; +	int stream_id; +} video_spu_t; + + +typedef struct video_spu_palette {      /* SPU Palette information */ +	int length; +	uint8_t *palette; +} video_spu_palette_t; + + +typedef struct video_navi_pack { +	int length;          /* 0 ... 1024 */ +	uint8_t data[1024]; +} video_navi_pack_t; + + +typedef uint16_t video_attributes_t; +/*   bits: descr. */ +/*   15-14 Video compression mode (0=MPEG-1, 1=MPEG-2) */ +/*   13-12 TV system (0=525/60, 1=625/50) */ +/*   11-10 Aspect ratio (0=4:3, 3=16:9) */ +/*    9- 8 permitted display mode on 4:3 monitor (0=both, 1=only pan-sca */ +/*    7    line 21-1 data present in GOP (1=yes, 0=no) */ +/*    6    line 21-2 data present in GOP (1=yes, 0=no) */ +/*    5- 3 source resolution (0=720x480/576, 1=704x480/576, 2=352x480/57 */ +/*    2    source letterboxed (1=yes, 0=no) */ +/*    0    film/camera mode (0=camera, 1=film (625/50 only)) */ + + +/* bit definitions for capabilities: */ +/* can the hardware decode MPEG1 and/or MPEG2? */ +#define VIDEO_CAP_MPEG1   1  +#define VIDEO_CAP_MPEG2   2 +/* can you send a system and/or program stream to video device? +   (you still have to open the video and the audio device but only  +    send the stream to the video device) */ +#define VIDEO_CAP_SYS     4 +#define VIDEO_CAP_PROG    8 +/* can the driver also handle SPU, NAVI and CSS encoded data?  +   (CSS API is not present yet) */ +#define VIDEO_CAP_SPU    16 +#define VIDEO_CAP_NAVI   32 +#define VIDEO_CAP_CSS    64 + + +#define VIDEO_STOP                 _IO('o', 21)  +#define VIDEO_PLAY                 _IO('o', 22) +#define VIDEO_FREEZE               _IO('o', 23) +#define VIDEO_CONTINUE             _IO('o', 24) +#define VIDEO_SELECT_SOURCE        _IO('o', 25) +#define VIDEO_SET_BLANK            _IO('o', 26) +#define VIDEO_GET_STATUS           _IOR('o', 27, struct video_status) +#define VIDEO_GET_EVENT            _IOR('o', 28, struct video_event) +#define VIDEO_SET_DISPLAY_FORMAT   _IO('o', 29) +#define VIDEO_STILLPICTURE         _IOW('o', 30, struct video_still_picture) +#define VIDEO_FAST_FORWARD         _IO('o', 31) +#define VIDEO_SLOWMOTION           _IO('o', 32) +#define VIDEO_GET_CAPABILITIES     _IOR('o', 33, unsigned int) +#define VIDEO_CLEAR_BUFFER         _IO('o',  34) +#define VIDEO_SET_ID               _IO('o', 35) +#define VIDEO_SET_STREAMTYPE       _IO('o', 36) +#define VIDEO_SET_FORMAT           _IO('o', 37) +#define VIDEO_SET_SYSTEM           _IO('o', 38) +#define VIDEO_SET_HIGHLIGHT        _IOW('o', 39, video_highlight_t) +#define VIDEO_SET_SPU              _IOW('o', 50, video_spu_t) +#define VIDEO_SET_SPU_PALETTE      _IOW('o', 51, video_spu_palette_t) +#define VIDEO_GET_NAVI             _IOR('o', 52, video_navi_pack_t) +#define VIDEO_SET_ATTRIBUTES       _IO('o', 53) +#define VIDEO_GET_SIZE             _IOR('o', 55, video_size_t) + +#endif /*_DVBVIDEO_H_*/ + diff --git a/libdvb2/README b/libdvb2/README new file mode 100644 index 0000000..049acd6 --- /dev/null +++ b/libdvb2/README @@ -0,0 +1,23 @@ +Late in 2003 the idea to create a simple DVB library from the code snippets +in the test/utility programs was discussed on the linux-dvb mailing list. +Hopefully someone will invest some time in this project to turn the idea into +reality... + +Here is an outline of what libdvb2 should be, according to my recollection: +(For first hand information search the linux-dvb list archives for "libdvb2".) + +- C +- small: The goal is to make the library usable in *any* DVB project, which +  is easier if the library sticks to the basics. Advanced stuff can be +  done in a second library. What exacty "basic" and "advanced" means +  is subject of discussion, but I want avoid to impose a certain programming +  model (e.g. multi-threaded vw. event-loop) on users of the library. +- a prime target is to establish a standard DVB config and service list +  format, to make this sharable between different applications +- LGPL + +About the name: There already is a libdvb written by the Metzler Bros., +but the main drawback is that it is written in C++ and thus rejected +by many projects. + +Johannes Stezenbach <js@convergence.de> diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..ddff9ab --- /dev/null +++ b/test/Makefile @@ -0,0 +1,37 @@ +# Makefile for Linux DVB API Version 3 test programs + +CC = gcc +CFLAGS = -g -O2 -W -Wall -I../include + +TARGETS = \ +	diseqc		\ +	set22k		\ +	sendburst	\ +	setvoltage	\ +	setpid		\ +	video		\ +	test_sections	\ +	test_sec_ne	\ +	test_pes	\ +	test_dvr	\ +	test_dvr_play	\ +	test_tt		\ +	test_av		\ +	test_av_play	\ +	test_vevent	\ +	test_stc	\ +	test_stillimage + +#	test		\ +#	test_audio	\ +#	test_front	\ +#	test_switch	\ +#	test_video	\ + +all: $(TARGETS) + +test_sections test_sec_ne test_pes test_tt: hex_dump.o + +clean: +	rm -f $(TARGETS) *.o + diff --git a/test/README b/test/README new file mode 100644 index 0000000..b3f0cac --- /dev/null +++ b/test/README @@ -0,0 +1,51 @@ +Various small test/sample programs for the Linux DVB API Version 2 + +The default devices used by the test programs are generally +/dev/dvb/adapter0/*0, and can be overridden using environment +variables: + +  FRONTEND=/dev/dvb/adapter0/frontend0 +  DEMUX=/dev/dvb/adapter0/demux0 +  DVR=/dev/dvb/adapter0/dvr0 +  AUDIO=/dev/dvb/adapter0/audio0 +  VIDEO=/dev/dvb/adapter0/video0 +  NET=/dev/dvb/adapter0/net0 + + +diseqc		: Send various diseqc sequences on a SAT frontend. +		  Best used with a diseqc test box with some LEDs to +		  show the result of the commands. +set22k		: Legacy tone switching for SAT frontends. +setvoltage	: Legacy voltage switching for SAT frontends. + +setpid		: Set video and audio PIDs in the demux; useful only +		  if you have a hardware MPEG decoder. +video		: A tiny video watching application, just starts capturing /dev/video +		  into /dev/fb0. +		  WARNING: May crash your box or mess up your console! + +test_sections	: Hex dump of section data from stream. +test_sec_ne	: Like test_sections, but also test Not-Equal filter mode. +test_pes	: Hex dump of PES data from stream. +test_tt		: Demonstrate teletext decoding from PES data. +test_av		: Test audio and video MPEG decoder API. +test_vevent	: Test VIDEO_GET_EVENT and poll() for video events +test_stc	: Test DMX_GET_STC. + +test_stillimage : Display single iframes as stillimages +		  iframes can be created with the 'convert' tool from  +		  imagemagick and mpeg2encode from ftp.mpeg.org, and must  +		  have a supported size, e.g. 702x576 +		  ($ convert -sample 702x576\! test.jpg test.mpg) + +(test_av_play	: Test playing MPEG TS from a file (apparently broken)) + + +test		: +test_audio	: +test_dmx	: +test_dvr	: +test_front	: +test_switch	: +test_video	: + diff --git a/test/dia b/test/dia new file mode 100755 index 0000000..5cb2600 --- /dev/null +++ b/test/dia @@ -0,0 +1,7 @@ +#!/bin/sh + +for f in $@ +do /usr/X11R6/bin/convert  -geomtry 702x576 $f test.mpg +test_video test.mpg +rm test.mpg +done
\ No newline at end of file diff --git a/test/diseqc.c b/test/diseqc.c new file mode 100644 index 0000000..8f2e411 --- /dev/null +++ b/test/diseqc.c @@ -0,0 +1,140 @@ +/* + * Test sending DiSEqC commands on a SAT frontend. + * + * usage: FRONTEND=/dev/dvb/adapterX/frontendX diseqc [test_seq_no] + */ + +#include <pthread.h> +#include <time.h> +#include <stdlib.h> +#include <stdint.h> +#include <stdio.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <linux/dvb/frontend.h> + + +struct diseqc_cmd { +	struct dvb_diseqc_master_cmd cmd; +	uint32_t wait; +}; + + +struct diseqc_cmd switch_cmds[] = { +	{ { { 0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf2, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf1, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf3, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf4, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf6, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf5, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf7, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf8, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfa, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf9, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfb, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfc, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfe, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfd, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xff, 0x00, 0x00 }, 4 }, 0 } +}; + + +/*--------------------------------------------------------------------------*/ + +static inline +void msleep(uint32_t msec) +{ +	struct timespec req = { msec / 1000, 1000000 * (msec % 1000) }; + +	while (nanosleep(&req, &req)) +		; +} + + +static +void diseqc_send_msg(int fd, fe_sec_voltage_t v, struct diseqc_cmd **cmd, +		     fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b) +{ +	ioctl(fd, FE_SET_TONE, SEC_TONE_OFF); +	ioctl(fd, FE_SET_VOLTAGE, v); + +	msleep(15); +	while (*cmd) { +		printf("msg: %02x %02x %02x %02x %02x %02x\n", +		       (*cmd)->cmd.msg[0], (*cmd)->cmd.msg[1], +		       (*cmd)->cmd.msg[2], (*cmd)->cmd.msg[3], +		       (*cmd)->cmd.msg[4], (*cmd)->cmd.msg[5]); + +		ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &(*cmd)->cmd); +		msleep((*cmd)->wait); +		cmd++; +	} + +	printf("%s: ", __FUNCTION__); + +	printf(" %s ", v == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : +	       v == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "???"); + +	printf(" %s ", b == SEC_MINI_A ? "SEC_MINI_A" : +	       b == SEC_MINI_B ? "SEC_MINI_B" : "???"); + +	printf(" %s\n", t == SEC_TONE_ON ? "SEC_TONE_ON" : +	       t == SEC_TONE_OFF ? "SEC_TONE_OFF" : "???"); + +	msleep(15); +	ioctl(fd, FE_DISEQC_SEND_BURST, b); + +	msleep(15); +	ioctl(fd, FE_SET_TONE, t); +} + + +int main(int argc, char **argv) +{ +	struct diseqc_cmd *cmd[2] = { NULL, NULL }; +	char *fedev = "/dev/dvb/adapter0/frontend0"; +	int fd; + +	if (getenv("FRONTEND")) +		fedev = getenv("FRONTEND"); + +	printf("diseqc test: using '%s'\n", fedev); + +	if ((fd = open(fedev, O_RDWR)) < 0) { +		perror("open"); +		return -1; +	} + +	if (argc > 1) { +		int i = atol(argv[1]); +		cmd[0] = &switch_cmds[i]; +		diseqc_send_msg(fd, +				i % 2 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13, +				cmd, +				(i/2) % 2 ? SEC_TONE_ON : SEC_TONE_OFF, +				(i/4) % 2 ? SEC_MINI_B : SEC_MINI_A); +	} else { +		unsigned int j; + +		for (j=0; j<sizeof(switch_cmds)/sizeof(struct diseqc_cmd); j++) +		{ +			cmd[0] = &switch_cmds[j]; +			diseqc_send_msg(fd, +					j % 2 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13, +					cmd, +					(j/2) % 2 ? SEC_TONE_ON : SEC_TONE_OFF, +					(j/4) % 2 ? SEC_MINI_B : SEC_MINI_A); +			msleep (1000); +		} +	} + +	close(fd); + +	return 0; +} + + diff --git a/test/hex_dump.c b/test/hex_dump.c new file mode 100644 index 0000000..c7c8ede --- /dev/null +++ b/test/hex_dump.c @@ -0,0 +1,63 @@ +/* hex_dump.h -- simple hex dump routine + * + * Copyright (C) 2002 convergence GmbH + * Johannes Stezenbach <js@convergence.de> + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +#include <stdio.h> +#include <stdlib.h> + +#include "hex_dump.h" + + +void hex_dump(uint8_t data[], int bytes) +{ +	int i, j; +	uint8_t c; + +	for (i = 0; i < bytes; i++) { +		if (!(i % 8) && i) +			printf(" "); +		if (!(i % 16) && i) { +			printf("  "); +			for (j = 0; j < 16; j++) { +				c = data[i+j-16]; +				if ((c < 0x20) || (c >= 0x7f)) +					c = '.'; +				printf("%c", c); +			} +			printf("\n"); +		} +		printf("%.2x ", data[i]); +	} +	j = (bytes % 16); +	j = (j != 0 ? j : 16); +	for (i = j; i < 16; i++) { +		if (!(i % 8) && i) +			printf(" "); +		printf("   "); +	} +	printf("   "); +	for (i = bytes - j; i < bytes; i++) { +		c = data[i]; +		if ((c < 0x20) || (c >= 0x7f)) +			c = '.'; +		printf("%c", c); +	} +	printf("\n"); +} + diff --git a/test/hex_dump.h b/test/hex_dump.h new file mode 100644 index 0000000..030cc37 --- /dev/null +++ b/test/hex_dump.h @@ -0,0 +1,28 @@ +#ifndef _HEXDUMP_H_ +#define _HEXDUMP_H_ +/* hex_dump.h -- simple hex dump routine + * + * Copyright (C) 2002 convergence GmbH + * Johannes Stezenbach <js@convergence.de> + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +#include <stdint.h> + +extern void hex_dump(uint8_t data[], int bytes); + + +#endif /* _HEXDUMP_H_ */ diff --git a/test/sendburst.c b/test/sendburst.c new file mode 100644 index 0000000..a96b68c --- /dev/null +++ b/test/sendburst.c @@ -0,0 +1,55 @@ +/* + * Test sending the burst mini command A/B on a SAT frontend. + * + * usage: FRONTEND=/dev/dvb/adapterX/frontendX sendburst {a|b} + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <linux/dvb/frontend.h> + + +int main (int argc, char **argv) +{ +   char *fedev = "/dev/dvb/adapter0/frontend0"; +   int fd, r; + +   if (argc != 2 || (strcmp(argv[1], "a") && strcmp(argv[1], "b"))) { +      fprintf (stderr, "usage: %s <a|b>\n", argv[0]); +      return 1; +   } + +   if (getenv("FRONTEND")) +	   fedev = getenv("FRONTEND"); + +   printf("set22k: using '%s'\n", fedev); + +   if ((fd = open (fedev, O_RDWR)) < 0) { +      perror ("open"); +      return 1; +   } + +   ioctl (fd, FE_SET_TONE, SEC_TONE_OFF); + +   usleep (30000);    /*  30ms according to DiSEqC spec  */ + +   if (strcmp(argv[1], "a") == 0) +      r = ioctl (fd, FE_DISEQC_SEND_BURST, SEC_MINI_A); +   else +      r = ioctl (fd, FE_DISEQC_SEND_BURST, SEC_MINI_B); + +   if (r == -1) +      perror("ioctl FE_SET_TONE"); + +   close (fd); + +   return 0; +} + diff --git a/test/set22k.c b/test/set22k.c new file mode 100644 index 0000000..51ffa1c --- /dev/null +++ b/test/set22k.c @@ -0,0 +1,50 @@ +/* + * Test switching the 22kHz tone signal on and off on a SAT frontend. + * (Note: DiSEqC equipment ignores this after it has once seen a diseqc + *  sequence; reload the driver or unplug/replug the SAT cable to reset.) + * + * usage: FRONTEND=/dev/dvb/adapterX/frontendX set22k {on|off} + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <linux/dvb/frontend.h> + + +int main (int argc, char **argv) +{ +   char *fedev = "/dev/dvb/adapter0/frontend0"; +   int fd, r; + +   if (argc != 2 || (strcmp(argv[1], "on") && strcmp(argv[1], "off"))) { +      fprintf (stderr, "usage: %s <on|off>\n", argv[0]); +      return 1; +   } +   if (getenv("FRONTEND")) +	   fedev = getenv("FRONTEND"); +   printf("set22k: using '%s'\n", fedev); + +   if ((fd = open (fedev, O_RDWR)) < 0) { +      perror ("open"); +      return 1; +   } + +   if (strcmp(argv[1], "on") == 0) +      r = ioctl (fd, FE_SET_TONE, SEC_TONE_ON); +   else +      r = ioctl (fd, FE_SET_TONE, SEC_TONE_OFF); +   if (r == -1) +	   perror("ioctl FE_SET_TONE"); + +   close (fd); + +   return 0; +} + diff --git a/test/setpid.c b/test/setpid.c new file mode 100644 index 0000000..fa0333c --- /dev/null +++ b/test/setpid.c @@ -0,0 +1,87 @@ +/* + * Set video and audio PIDs in the demux; useful only if you have + * a hardware MPEG decoder and you're tuned to a transport stream. + * + * usage: DEMUX=/dev/dvb/adapterX/demuxX setpid video_pid audio_pid + */ + +#include <unistd.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <stdio.h> +#include <linux/dvb/dmx.h> + + +static +int setup_demux (char *dmxdev, int video_pid, int audio_pid) +{ +   int vfd, afd; +   struct dmx_pes_filter_params pesfilter; + +   printf ("video_pid == 0x%04x\n", video_pid); +   printf ("audio_pid == 0x%04x\n", audio_pid); + +   if ((vfd = open (dmxdev, O_RDWR)) < 0) { +      perror("open 1"); +      return -1; +   } + +   pesfilter.pid = video_pid; +   pesfilter.input = DMX_IN_FRONTEND; +   pesfilter.output = DMX_OUT_DECODER; +   pesfilter.pes_type = DMX_PES_VIDEO; +   pesfilter.flags = DMX_IMMEDIATE_START; + +   if (ioctl (vfd, DMX_SET_PES_FILTER, &pesfilter) < 0) { +      perror("ioctl DMX_SET_PES_FILTER (video)"); +      return -1; +   } + +   close (vfd); + +   if ((afd = open (dmxdev, O_RDWR)) < 0) { +      perror("open 1"); +      return -1; +   } + +   pesfilter.pid = audio_pid; +   pesfilter.input = DMX_IN_FRONTEND; +   pesfilter.output = DMX_OUT_DECODER; +   pesfilter.pes_type = DMX_PES_AUDIO; +   pesfilter.flags = DMX_IMMEDIATE_START; + +   if (ioctl (afd, DMX_SET_PES_FILTER, &pesfilter) < 0) { +      perror("ioctl DMX_SET_PES_FILTER (audio)"); +      return -1; +   } + +   close (afd); +   return 0; +} + + +int main (int argc, char **argv) +{ +   char *dmxdev = "/dev/dvb/adapter0/demux0"; +   int video_pid, audio_pid; + +   if (argc != 3) { +      printf ("\nusage: %s <video pid> <audio pid>\n\n", argv[0]); +      exit (1); +   } +   if (getenv("DEMUX")) +      dmxdev = getenv("DEMUX"); +   printf("setpid: using '%s'\n", dmxdev); + +   video_pid = strtol(argv[1], NULL, 0); +   audio_pid = strtol(argv[2], NULL, 0); +   if (setup_demux (dmxdev, video_pid, audio_pid) < 0) +      return 1; + +   return 0; +} + + diff --git a/test/setvoltage.c b/test/setvoltage.c new file mode 100644 index 0000000..1d14a4c --- /dev/null +++ b/test/setvoltage.c @@ -0,0 +1,47 @@ +/* + * Test switching the voltage signal high and low on a SAT frontend. + * (Note: DiSEqC equipment ignores this after it has once seen a diseqc + *  sequence; reload the driver or unplug/replug the SAT cable to reset.) + * + * usage: FRONTEND=/dev/dvb/adapterX/frontendX setvoltage {13|18} + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <linux/dvb/frontend.h> + + +int main (int argc, char **argv) +{ +   char *fedev = "/dev/dvb/adapter0/frontend0"; +   int fd, r; + +   if (argc != 2 || (strcmp(argv[1], "13") && strcmp(argv[1], "18"))) { +      fprintf (stderr, "usage: %s <13|18>\n", argv[0]); +      return -1; +   } +   if (getenv("FRONTEND")) +	   fedev = getenv("FRONTEND"); +   printf("setvoltage: using '%s'\n", fedev); + +   if ((fd = open (fedev, O_RDWR)) < 0) +      perror ("open"); + +   if (strcmp(argv[1], "13") == 0) +      r = ioctl (fd, FE_SET_VOLTAGE, SEC_VOLTAGE_13); +   else +      r = ioctl (fd, FE_SET_VOLTAGE, SEC_VOLTAGE_18); +   if (r == -1) +	   perror ("ioctl FE_SET_VOLTAGE"); + +   close (fd); + +   return 0; +} + diff --git a/test/test.c b/test/test.c new file mode 100644 index 0000000..6c9af51 --- /dev/null +++ b/test/test.c @@ -0,0 +1,281 @@ +/*  + * test.c - Test program for new API + * + * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> +                      for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> + +#include <linux/dvb/dmx.h> +#include <linux/dvb/frontend_old.h> +#include <linux/dvb/sec.h> +#include <linux/dvb/video.h> + +uint8_t reverse[] = { +0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0, +0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8, +0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4, +0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC, +0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2, +0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA, +0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6, +0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE, +0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1, +0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9, +0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5, +0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD, +0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3, +0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB, +0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7, +0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF +}; + +inline t2a(uint8_t c) +{ +  c=reverse[c]&0x7f; +  if (c<0x20) +    c=0x20; +  +  return c; +} + +void testpesfilter(void) +{ +        uint8_t buf[4096], id; +	int i,j; +	int len; +	int fd=open("/dev/ost/demux1", O_RDWR); +	struct dmx_pes_filter_params pesFilterParams;  +	 +	pesFilterParams.input = DMX_IN_FRONTEND;  +	pesFilterParams.output = DMX_OUT_TS_TAP;  +	pesFilterParams.pes_type = DMX_PES_TELETEXT;  +	pesFilterParams.flags = DMX_IMMEDIATE_START; +   +	pesFilterParams.pid = 0x2c ; +	if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { +	        printf("Could not set PES filter\n");  +		close(fd); +		return; +	} +	ioctl(fd, DMX_STOP, 0); +/* +	pesFilterParams.pid = 54; +	if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { +	        printf("Could not set PES filter\n");  +		close(fd); +		return; +	} +	ioctl(fd, DMX_STOP, 0); + +	pesFilterParams.pid = 55; +	if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { +	        printf("Could not set PES filter\n");  +		close(fd); +		return; +	} +*/ +	while(1) { +		len=read(fd, buf, 4096); +		if (len>0) write(1, buf, len); +	} + +	do {  +	        read(fd, buf, 4); +		if (htonl(*(uint32_t *)buf)!=0x00001bd) +		        continue; +		read(fd, buf+4, 2); +		len=(buf[4]<<8)|buf[5]; +	        read(fd, buf+6, len); +		fprintf(stderr,"read %d bytes PES\n", len); +		write (1, buf, len+6); +		 +		id=buf[45]; +		fprintf(stderr,"id=%02x\n", id); +		 +		for (i=0; i<(len+6-46)/46; i++) { +		  for (j=6; j<46; j++) { +		    fprintf(stderr,"%c", t2a(buf[i*46+46+j])); +		  } +		    fprintf(stderr,"\n"); +		} + +	} while (1); + + +	/* +	pesFilterParams.pid = 55; +	pesFilterParams.input = DMX_IN_FRONTEND;  +	pesFilterParams.output = DMX_OUT_DECODER;  +	pesFilterParams.pes_type = DMX_PES_TELETEXT;  +	pesFilterParams.flags = DMX_IMMEDIATE_START; +   +	ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams); +	close(fd); +	*/ +} + + +senf() +{ +  int ret; +  int len; +  struct secCommand scmd; +  struct secCmdSequence scmds; +  struct dmx_pes_filter_params pesFilterParams;  +  struct dmx_sct_filter_params secFilterParams;  +  FrontendParameters frp; +  uint8_t buf[4096]; + +  int vout=open("qv", O_RDWR|O_CREAT); +  int aout=open("qa", O_RDWR|O_CREAT); + +  int fd_video=open("/dev/ost/video", O_RDWR); +  int fd_audio=open("/dev/ost/audio", O_RDWR); +  int fd_tt=open("/dev/ost/demux", O_RDWR); +  int fd_frontend=open("/dev/ost/frontend", O_RDWR); +  int fd_sec=open("/dev/ost/sec", O_RDWR); +  int fd_demux=open("/dev/ost/demux", O_RDWR|O_NONBLOCK); +  int fd_demux2=open("/dev/ost/demux", O_RDWR|O_NONBLOCK); +  int fd_section=open("/dev/ost/demux", O_RDWR); +  int fd_section2=open("/dev/ost/demux", O_RDWR); + +  printf("%d\n",fd_section); + +  //if (ioctl(fd_sec, SEC_SET_VOLTAGE, SEC_VOLTAGE_13) < 0)  return; +  //if (ioctl(fd_sec, SEC_SET_TONE, SEC_TONE_ON) < 0)  return; +#if 0 +  scmd.type=0; +  scmd.u.diseqc.addr=0x10; +  scmd.u.diseqc.cmd=0x38; +  scmd.u.diseqc.numParams=1; +  scmd.u.diseqc.params[0]=0xf0; +   +  scmds.voltage=SEC_VOLTAGE_13; +  scmds.miniCommand=SEC_MINI_NONE; +  scmds.continuousTone=SEC_TONE_ON; +  scmds.numCommands=1; +  scmds.commands=&scmd; +  if (ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds) < 0)  return; +  printf("SEC OK\n"); + +  frp.Frequency=(12666000-10600000); +  frp.u.qpsk.SymbolRate=22000000; +  frp.u.qpsk.FEC_inner=FEC_AUTO; + +  if (ioctl(fd_frontend, FE_SET_FRONTEND, &frp) < 0)  return; +  printf("QPSK OK\n"); +#endif + +#if 0 +  ret=ioctl(fd_demux2, DMX_SET_BUFFER_SIZE, 64*1024); +    if (ret<0) +      perror("DMX_SET_BUFFER_SIZE\n"); +  printf("Audio filter size OK\n"); +  pesFilterParams.pid = 0x60;  +  pesFilterParams.input = DMX_IN_FRONTEND;  +  pesFilterParams.output = DMX_OUT_DECODER;  +  pesFilterParams.pes_type = DMX_PES_AUDIO;  +  pesFilterParams.flags = DMX_IMMEDIATE_START; +   +  if (ioctl(fd_demux2, DMX_SET_PES_FILTER, &pesFilterParams) < 0)   return(1);  +  printf("Audio filter OK\n"); +   +  if (ioctl(fd_demux, DMX_SET_BUFFER_SIZE, 64*1024) < 0)  return(1);  +  pesFilterParams.pid = 0xa2; +  pesFilterParams.input = DMX_IN_FRONTEND;  +  pesFilterParams.output = DMX_OUT_DECODER;  +  pesFilterParams.pes_type = DMX_PES_VIDEO;  +  pesFilterParams.flags = DMX_IMMEDIATE_START; +  if (ioctl(fd_demux, DMX_SET_PES_FILTER, &pesFilterParams) < 0)  return(1);  +  printf("Video filter OK\n"); +#endif +  /* +  pesFilterParams.pid = 56; +  pesFilterParams.input = DMX_IN_FRONTEND;  +  pesFilterParams.output = DMX_OUT_DECODER;  +  pesFilterParams.pes_type = DMX_PES_TELETEXT;  +  pesFilterParams.flags = DMX_IMMEDIATE_START; +  if (ioctl(fd_tt, DMX_SET_PES_FILTER, &pesFilterParams) < 0)  return(1);  +  printf("TT filter OK\n"); +  */ +  //while (1); +  /* { +    len=read(fd_demux, buf, 4096); +    if (len>0) write (vout, buf, len); +    len=read(fd_demux2, buf, 4096); +    if (len>0) write (aout, buf, len); +    }*/ + + +  memset(&secFilterParams.filter.filter, 0, DMX_FILTER_SIZE); +  memset(&secFilterParams.filter.mask, 0, DMX_FILTER_SIZE); +  secFilterParams.filter.filter[0]=0x00; +  secFilterParams.filter.mask[0]=0x00; +  secFilterParams.timeout=5000; +  secFilterParams.flags=DMX_IMMEDIATE_START; + +  /* +  // this one should timeout after 2 seconds +  secFilterParams.pid=0xa4; +  if (ioctl(fd_section, DMX_SET_FILTER, &secFilterParams) < 0)  return; +  len=read(fd_section, buf, 4096); +  */ + +  /* +  { +    int32_t snr, str; +    ioctl(fd_frontend, FE_READ_SNR, &snr); +    ioctl(fd_frontend, FE_READ_SIGNAL_STRENGTH, &str); +     +    printf("snr=%d, str=%d\n", snr, str); +  } +  */ + +  secFilterParams.pid=0x11; +  //printf("section filter\n"); +  if (ioctl(fd_section, DMX_SET_FILTER, &secFilterParams) < 0)  return; +  //if (ioctl(fd_section2, DMX_SET_FILTER, &secFilterParams) < 0)  return; +  //close(fd_section2); +  //while (1)  +{ +    len=read(fd_section, buf, 4096); +    if (len>0) write(1, buf, len); +    //printf("read section with length %d\n", len); +    //if (len>0) write(1,buf,len); +    //len=read(fd_section2, buf, 4096); +    //if (len>0) write(1,buf,len); +    //printf("read section with length %d\n", len); +  } +   +} + +main() +{ +	//senf(); +  testpesfilter(); +} + diff --git a/test/test_audio.c b/test/test_audio.c new file mode 100644 index 0000000..0abb734 --- /dev/null +++ b/test/test_audio.c @@ -0,0 +1,345 @@ +/*  + * test_audio.c - Test program for new API + * + * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> +                      for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <ost/dmx.h> +#include <ost/frontend_old.h> +#include <ost/sec.h> +#include <ost/audio.h> +#include <sys/poll.h> + +int audioStop(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_STOP,0) < 0)){ +		perror("AUDIO STOP: "); +		return -1; +	} + +	return 0; +} + +int audioPlay(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_PLAY) < 0)){ +		perror("AUDIO PLAY: "); +		return -1; +	} + +	return 0; +} + + +int audioPause(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_PAUSE) < 0)){ +		perror("AUDIO PAUSE: "); +		return -1; +	} + +	return 0; +} + + +int audioContinue(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_CONTINUE) < 0)){ +		perror("AUDIO CONTINUE: "); +		return -1; +	} + +	return 0; +} + +int audioSelectSource(int fd, audio_stream_source_t source) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_SELECT_SOURCE, source) < 0)){ +		perror("AUDIO SELECT SOURCE: "); +		return -1; +	} + +	return 0; +} + + + +int audioSetMute(int fd, boolean state) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_SET_MUTE, state) < 0)){ +		perror("AUDIO SET MUTE: "); +		return -1; +	} + +	return 0; +} + +int audioSetAVSync(int fd,boolean state) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_SET_AV_SYNC, state) < 0)){ +		perror("AUDIO SET AV SYNC: "); +		return -1; +	} + +	return 0; +} + +int audioSetBypassMode(int fd,boolean mode) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_SET_BYPASS_MODE, mode) < 0)){ +		perror("AUDIO SET BYPASS MODE: "); +		return -1; +	} + +	return 0; +} + + +int audioChannelSelect(int fd, audio_channel_select_t select) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_CHANNEL_SELECT, select) < 0)){ +		perror("AUDIO CHANNEL SELECT: "); +		return -1; +	} + +	return 0; +} + +int audioGetStatus(int fd) +{ +	struct audio_status stat; +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_GET_STATUS, &stat) < 0)){ +		perror("AUDIO GET STATUS: "); +		return -1; +	} + +	printf("Audio Status:\n"); +	printf("  Sync State          : %s\n", +	       (stat.AV_sync_state ? "SYNC" : "NO SYNC")); +	printf("  Mute State          : %s\n", +	       (stat.mute_state ? "muted" : "not muted")); +	printf("  Play State          : "); +	switch ((int)stat.play_state){ +	case AUDIO_STOPPED: +		printf("STOPPED (%d)\n",stat.play_state); +		break; +	case AUDIO_PLAYING: +		printf("PLAYING (%d)\n",stat.play_state); +		break; +	case AUDIO_PAUSED: +		printf("PAUSED (%d)\n",stat.play_state); +		break; +	default: +		printf("unknown (%d)\n",stat.play_state); +		break; +	} +	 +	printf("  Stream Source       : "); +	switch((int)stat.stream_source){ +	case AUDIO_SOURCE_DEMUX: +		printf("DEMUX (%d)\n",stat.stream_source); +		break; +	case AUDIO_SOURCE_MEMORY: +		printf("MEMORY (%d)\n",stat.stream_source); +		break; +	default: +		printf("unknown (%d)\n",stat.stream_source); +		break; +	} + +	printf("  Channel Select      : "); +	switch((int)stat.channel_select){ +	case AUDIO_STEREO: +		printf("Stereo (%d)\n",stat.channel_select); +		break; +	case AUDIO_MONO_LEFT: +		printf("Mono left(%d)\n",stat.channel_select); +		break; +	case AUDIO_MONO_RIGHT: +		printf("Mono right (%d)\n",stat.channel_select); +		break; +	default: +		printf("unknown (%d)\n",stat.channel_select); +		break; +	} +	printf("  Bypass Mode         : %s\n", +	       (stat.bypass_mode ? "ON" : "OFF")); + +	return 0; + +} + +#define BUFFY 100000 +#define NFD   2 +play_file_audio(int filefd, int fd) +{ +	char buf[BUFFY]; +	int count; +	int written; +	int ch; +	struct pollfd pfd[NFD]; +	int stopped = 0; +	boolean mute = false; +	boolean sync = false; +	 +	pfd[0].fd = STDIN_FILENO; +	pfd[0].events = POLLIN; + +	pfd[1].fd = fd; +	pfd[1].events = POLLOUT; + + +	while ( (count = read(filefd,buf,BUFFY)) >= 0  ){ +		written = 0; +		while(written < count){ +			if (poll(pfd,NFD,1)){ +				if (pfd[1].revents & POLLOUT){ +					written += write(fd,buf+written, +							count-written); +				} +				if (pfd[0].revents & POLLIN){ +					int c = getchar(); +					switch(c){ +					case 'z': +						audioPause(fd); +						printf("playback paused\n"); +						stopped = 1; +						break; + +					case 's': +						audioStop(fd); +						printf("playback stopped\n"); +						stopped = 1; +						break; +						 +					case 'c': +						audioContinue(fd); +						printf("playback continued\n"); +						stopped = 0; +						break; + +					case 'p': +						audioPlay(fd); +						printf("playback started\n"); +						stopped = 0; +						break; + +					case 'm': +						if (mute==false)mute=true; +						else mute=false; +						audioSetMute(fd,mute); +						printf("mute %d\n",mute); +						break; + +					case 'a': +						if (sync==false)sync=true; +						else sync=false; +						audioSetAVSync(fd,sync); +						printf("AV sync %d\n",sync); +						stopped = 0; +						break; + +					case 'q': +						audioContinue(fd); +						exit(0); +						break; +					} +				} +				 +			} +		} +	} + +} + + +main(int argc, char **argv) +{ +	int fd; +	int filefd; +	boolean mute = false; +	boolean sync = false; + +	if (argc < 2) return -1; + +	if ( (filefd = open(argv[1],O_RDONLY)) < 0){ +		perror("File open:"); +		return -1; +	} +	     +	if((fd = open("/dev/ost/audio",O_RDWR|O_NONBLOCK)) < 0){ +		perror("AUDIO DEVICE: "); +		return -1; +	} + + + +	audioSetMute(fd,mute); +	//	audioSetBypassMode(fd,false); // not implemented +	//audioContinue(fd); +	audioSelectSource(fd,AUDIO_SOURCE_MEMORY); +	audioPlay(fd); +	//sleep(4); +	//audioPause(fd); +	//sleep(3); +	//audioContinue(fd); +	//sleep(3); +	//audioStop(fd); +	//audioChannelSelect(fd,AUDIO_STEREO); +	//audioSetAVSync(fd,sync); +	audioGetStatus(fd); +	 +	play_file_audio(filefd,fd); + +	close(fd); +	return 0; + + +} + diff --git a/test/test_av.c b/test/test_av.c new file mode 100644 index 0000000..5d77000 --- /dev/null +++ b/test/test_av.c @@ -0,0 +1,574 @@ +/*  + * test_av.c - Test for audio and video MPEG decoder API. + * + * Copyright (C) 2000 - 2002 convergence GmbH + * Ralph Metzler <rjkm@convergence.de> + * Marcus Metzler <mocm@convergence.de> + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +#include <sys/ioctl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <linux/dvb/audio.h> +#include <linux/dvb/video.h> + +int audioStop(int fd, char *arg) +{ +	if (arg) +		return -1; +	if (ioctl(fd, AUDIO_STOP) == -1) +		perror("AUDIO_STOP"); +	return 0; +} + +int audioPlay(int fd, char *arg) +{ +	if (arg) +		return -1; +	if (ioctl(fd, AUDIO_PLAY)  == -1) +		perror("AUDIO_PLAY"); +	return 0; +} + +int audioPause(int fd, char *arg) +{ +	if (arg) +		return -1; +	if (ioctl(fd, AUDIO_PAUSE) == -1) +		perror("AUDIO_PAUSE"); +	return 0; +} + + +int audioContinue(int fd, char *arg) +{ +	if (arg) +		return -1; +	if (ioctl(fd, AUDIO_CONTINUE) == -1) +		perror("AUDIO_CONTINUE"); +	return 0; +} + +int audioSelectSource(int fd, char *arg) +{ +	int source; +	if (!arg) +		return -1; +	source = atoi(arg); +	if (ioctl(fd, AUDIO_SELECT_SOURCE, source) == -1) +		perror("AUDIO_SELECT_SOURCE"); +	return 0; +} + +int audioSetMute(int fd, char *arg) +{ +	int mute; +	if (!arg) +		return -1; +	mute = atoi(arg); +	if (ioctl(fd, AUDIO_SET_MUTE, mute) == -1) +		perror("AUDIO_SET_MUTE"); +	return 0; +} + +int audioSetAVSync(int fd, char *arg) +{ +	int sync; +	if (!arg) +		return -1; +	sync = atoi(arg); +	if (ioctl(fd, AUDIO_SET_AV_SYNC, sync) == -1) +		perror("AUDIO_SET_AV_SYNC"); +	return 0; +} + +int audioSetBypassMode(int fd, char *arg) +{ +	int byp; +	if (!arg) +		return -1; +	byp = atoi(arg); +	if (ioctl(fd, AUDIO_SET_BYPASS_MODE, byp) == -1) +		perror("AUDIO_SET_BYPASS_MODE"); +	return 0; +} + +int audioChannelSelect(int fd, char *arg) +{ +	int chan; +	if (!arg) +		return -1; +	chan = atoi(arg); +	if (ioctl(fd, AUDIO_CHANNEL_SELECT, chan) == -1) +		perror("AUDIO_CHANNEL_SELECT"); +	return 0; +} + +int audioGetStatus(int fd, char *arg) +{ +	struct audio_status stat; + +	if (arg) +		return -1; +	if (ioctl(fd, AUDIO_GET_STATUS, &stat) == -1) { +		perror("AUDIO_GET_STATUS"); +		return 0; +	} + +	printf("Audio Status:\n"); +	printf("  Sync State          : %s\n", +	       (stat.AV_sync_state ? "SYNC" : "NO SYNC")); +	printf("  Mute State          : %s\n", +	       (stat.mute_state ? "muted" : "not muted")); +	printf("  Play State          : "); +	switch ((int)stat.play_state){ +	case AUDIO_STOPPED: +		printf("STOPPED (%d)\n",stat.play_state); +		break; +	case AUDIO_PLAYING: +		printf("PLAYING (%d)\n",stat.play_state); +		break; +	case AUDIO_PAUSED: +		printf("PAUSED (%d)\n",stat.play_state); +		break; +	default: +		printf("unknown (%d)\n",stat.play_state); +		break; +	} + +	printf("  Stream Source       : "); +	switch((int)stat.stream_source){ +	case AUDIO_SOURCE_DEMUX: +		printf("DEMUX (%d)\n",stat.stream_source); +		break; +	case AUDIO_SOURCE_MEMORY: +		printf("MEMORY (%d)\n",stat.stream_source); +		break; +	default: +		printf("unknown (%d)\n",stat.stream_source); +		break; +	} + +	printf("  Channel Select      : "); +	switch((int)stat.channel_select){ +	case AUDIO_STEREO: +		printf("Stereo (%d)\n",stat.channel_select); +		break; +	case AUDIO_MONO_LEFT: +		printf("Mono left(%d)\n",stat.channel_select); +		break; +	case AUDIO_MONO_RIGHT: +		printf("Mono right (%d)\n",stat.channel_select); +		break; +	default: +		printf("unknown (%d)\n",stat.channel_select); +		break; +	} +	printf("  Bypass Mode         : %s\n", +	       (stat.bypass_mode ? "ON" : "OFF")); + +	return 0; + +} + +int videoStop(int fd, char *arg) +{ +	if (arg) +		return -1; +	if (ioctl(fd, VIDEO_STOP) == -1) +		perror("VIDEO_STOP"); +	return 0; +} + +int videoPlay(int fd, char *arg) +{ +	if (arg) +		return -1; +	if (ioctl(fd, VIDEO_PLAY) == -1) +		perror("VIDEO_PLAY"); +	return 0; +} + + +int videoFreeze(int fd, char *arg) +{ +	if (arg) +		return -1; +	if (ioctl(fd, VIDEO_FREEZE) == -1) +		perror("VIDEO_FREEZE"); +	return 0; +} + + +int videoContinue(int fd, char *arg) +{ +	if (arg) +		return -1; +	if (ioctl(fd, VIDEO_CONTINUE) == -1) +		perror("VIDEO_CONTINUE"); +	return 0; +} + +int videoFormat(int fd, char *arg) +{ +	int format; +	if (!arg) +		return -1; +	format = atoi(arg); +	if (ioctl(fd, VIDEO_SET_FORMAT, format) == -1) +		perror("VIDEO_SET_FORMAT"); +	return 0; +} + +int videoDisplayFormat(int fd, char *arg) +{ +	int format; +	if (!arg) +		return -1; +	format = atoi(arg); +	if (ioctl(fd, VIDEO_SET_DISPLAY_FORMAT, format) == -1) +		perror("VIDEO_SET_DISPLAY_FORMAT"); +	return 0; +} + +int videoSelectSource(int fd, char *arg) +{ +	int source; +	if (!arg) +		return -1; +	source = atoi(arg); +	if (ioctl(fd, VIDEO_SELECT_SOURCE, source) == -1) +		perror("VIDEO_SELECT_SOURCE"); +	return 0; +} + + + +int videoSetBlank(int fd, char *arg) +{ +	int blank; +	if (!arg) +		return -1; +	blank = atoi(arg); +	if (ioctl(fd, VIDEO_SET_BLANK, blank) == -1) +		perror("VIDEO_SET_BLANK"); +	return 0; +} + +int videoFastForward(int fd, char *arg) +{ +	int frames; +	if (!arg) +		return -1; +	frames = atoi(arg); +	if (ioctl(fd, VIDEO_FAST_FORWARD, frames) == -1) +		perror("VIDEO_FAST_FORWARD"); +	return 0; +} + +int videoSlowMotion(int fd, char *arg) +{ +	int frames; +	if (!arg) +		return -1; +	frames = atoi(arg); +	if (ioctl(fd, VIDEO_SLOWMOTION, frames) == -1) +		perror("VIDEO_SLOWMOTION"); +	return 0; +} + +int videoGetStatus(int fd, char *arg) +{ +	struct video_status stat; + +	if (arg) +		return -1; +	if (ioctl(fd, VIDEO_GET_STATUS, &stat) == -1){ +		perror("VIDEO_GET_STATUS"); +		return 0; +	} + +	printf("Video Status:\n"); +	printf("  Blank State          : %s\n", +	       (stat.video_blank ? "BLANK" : "STILL")); +	printf("  Play State           : "); +	switch ((int)stat.play_state){ +	case VIDEO_STOPPED: +		printf("STOPPED (%d)\n",stat.play_state); +		break; +	case VIDEO_PLAYING: +		printf("PLAYING (%d)\n",stat.play_state); +		break; +	case VIDEO_FREEZED: +		printf("FREEZED (%d)\n",stat.play_state); +		break; +	default: +		printf("unknown (%d)\n",stat.play_state); +		break; +	} + +	printf("  Stream Source        : "); +	switch((int)stat.stream_source){ +	case VIDEO_SOURCE_DEMUX: +		printf("DEMUX (%d)\n",stat.stream_source); +		break; +	case VIDEO_SOURCE_MEMORY: +		printf("MEMORY (%d)\n",stat.stream_source); +		break; +	default: +		printf("unknown (%d)\n",stat.stream_source); +		break; +	} + +	printf("  Format (Aspect Ratio): "); +	switch((int)stat.video_format){ +	case VIDEO_FORMAT_4_3: +		printf("4:3 (%d)\n",stat.video_format); +		break; +	case VIDEO_FORMAT_16_9: +		printf("16:9 (%d)\n",stat.video_format); +		break; +	case VIDEO_FORMAT_221_1: +		printf("2.21:1 (%d)\n",stat.video_format); +		break; +	default: +		printf("unknown (%d)\n",stat.video_format); +		break; +	} + +	printf("  Display Format       : "); +	switch((int)stat.display_format){ +	case VIDEO_PAN_SCAN: +		printf("Pan&Scan (%d)\n",stat.display_format); +		break; +	case VIDEO_LETTER_BOX: +		printf("Letterbox (%d)\n",stat.display_format); +		break; +	case VIDEO_CENTER_CUT_OUT: +		printf("Center cutout (%d)\n",stat.display_format); +		break; +	default: +		printf("unknown (%d)\n",stat.display_format); +		break; +	} +	return 0; +} + +int videoGetSize(int fd, char *arg) +{ +	video_size_t size; + +	if (arg) +		return -1; +	if (ioctl(fd, VIDEO_GET_SIZE, &size) == -1){ +		perror("VIDEO_GET_SIZE"); +		return 0; +	} + +	printf("Video Size: %ux%u ", size.w, size.h); +	switch (size.aspect_ratio) { +	case VIDEO_FORMAT_4_3: +		printf("4:3 (%d)\n", size.aspect_ratio); +		break; +	case VIDEO_FORMAT_16_9: +		printf("16:9 (%d)\n", size.aspect_ratio); +		break; +	case VIDEO_FORMAT_221_1: +		printf("2.21:1 (%d)\n", size.aspect_ratio); +		break; +	default: +		printf("unknown aspect ratio (%d)\n", size.aspect_ratio); +		break; +	} +	return 0; +} + +int videoStillPicture(int fd, char *arg) +{ +	int sifd; +	struct stat st; +	struct video_still_picture sp; + +	if (!arg) +		return -1; +	sifd = open(arg, O_RDONLY); +	if (sifd == -1) { +		perror("open stillimage file"); +		printf("(%s)\n", arg); +		return 0; +	} +	fstat(sifd, &st); + +	sp.iFrame = (char *) malloc(st.st_size); +	sp.size = st.st_size; +	printf("I-frame size: %d\n", sp.size); + +	if(!sp.iFrame) { +		printf("No memory for I-Frame\n"); +		return 0; +	} + +	printf("read: %d bytes\n",read(sifd,sp.iFrame,sp.size)); +	if (ioctl(fd, VIDEO_STILLPICTURE, &sp) == -1) +		perror("VIDEO_STILLPICTURE"); +	return 0; +} + +typedef int (* cmd_func_t)(int fd, char *args); +typedef struct { +	char *cmd; +	char *param_help; +	cmd_func_t cmd_func; +} cmd_t; +cmd_t audio_cmds[] = +{ +	{ "stop", "", audioStop }, +	{ "play", "", audioPlay }, +	{ "pause", "", audioPause }, +	{ "continue", "", audioContinue }, +	{ "source", "n: 0 demux, 1 memory", audioSelectSource }, +	{ "mute", "n: 0 unmute, 1 mute", audioSetMute }, +	{ "avsync", "n: 0 unsync, 1 sync", audioSetAVSync }, +	{ "bypass", "n: 0 normal, 1 bypass", audioSetBypassMode }, +	{ "channel", "n: 0 stereo, 1 left, 2 right", audioChannelSelect }, +	{ "status", "", audioGetStatus }, +	{ NULL, NULL, NULL } +}; +cmd_t video_cmds[] = +{ +	{ "stop", "", videoStop }, +	{ "play", "", videoPlay }, +	{ "freeze", "", videoFreeze }, +	{ "continue", "", videoContinue }, +	{ "source", "n: 0 demux, 1 memory", videoSelectSource }, +	{ "blank", "n: 0 normal, 1 blank", videoSetBlank }, +	{ "ff", "n: number of frames", videoFastForward }, +	{ "slow", "n: number of frames", videoSlowMotion }, +	{ "status", "", videoGetStatus }, +	{ "size", "", videoGetSize }, +	{ "stillpic", "filename", videoStillPicture}, +	{ "format", "n: 0 4:3, 1 16:9", videoFormat}, +	{ "dispformat", "n: 0 pan&scan, 1 letter box, 2 center cut out", videoDisplayFormat}, +	{ NULL, NULL, NULL } +}; +int usage(void) +{ +	int i; +	printf ("commands begin with a for audio and v for video:\n\n" +	        "q : quit\n"); +	for (i=0; audio_cmds[i].cmd; i++) +		printf("a %s %s\n", audio_cmds[i].cmd, audio_cmds[i].param_help); +	for (i=0; video_cmds[i].cmd; i++) +		printf("v %s %s\n", video_cmds[i].cmd, video_cmds[i].param_help); +	printf("\n"); +	return 0; +} + +int syntax_error(void) +{ +	fprintf(stderr, "syntax error\n"); +	return 0; +} + +int process_kbd_input(int vfd, int afd) +{ +	char buf[256], *cmd; +	int i; + +	if (!fgets(buf, sizeof(buf), stdin)) +		return -1; +	cmd = strtok(buf, " \n\t"); +	if (!cmd) { +		printf("enter command or h + enter for help\n"); +		return 0; +	} +	if (cmd[0] == 'q' || !strcmp(cmd, "quit")) +		return -1; +	if (cmd[0] == 'h' || !strcmp(cmd, "help")) +		return usage(); +	if (cmd[0] == 'a' || !strcmp(cmd, "audio")) { +		cmd = strtok(NULL, " \n\t"); +		if (!cmd) +			return syntax_error(); +		for (i=0; audio_cmds[i].cmd; i++) { +			if (!strcmp(cmd, audio_cmds[i].cmd)) { +				cmd = strtok(NULL, " \n\t"); +				printf("calling '%s', arg '%s'\n", audio_cmds[i].cmd, cmd); +				if (audio_cmds[i].cmd_func(afd, cmd)) +					syntax_error(); +				return 0; +			} +		} +		return syntax_error(); +	} else if (buf[0] == 'v') { +		cmd = strtok(NULL, " \n\t"); +		if (!cmd) +			return usage(); +		for (i=0; video_cmds[i].cmd; i++) { +			if (!strcmp(cmd, video_cmds[i].cmd)) { +				cmd = strtok(NULL, " \n\t"); +				printf("calling '%s', arg '%s'\n", video_cmds[i].cmd, cmd); +				if (video_cmds[i].cmd_func(vfd, cmd)) +					syntax_error(); +				return 0; +			} +		} +		return syntax_error(); +	} else +		return syntax_error(); +	return 0; +} + +int main(void) +{ +	int vfd, afd; +	char *videodev = "/dev/dvb/adapter0/video0"; +	char *audiodev = "/dev/dvb/adapter0/audio0"; + +	if (getenv("VIDEO")) +		videodev = getenv("VIDEO"); +	if (getenv("AUDIO")) +		videodev = getenv("AUDIO"); + +	printf("using video device '%s'\n", videodev); +	printf("using audio device '%s'\n", audiodev); +	printf("enter command or h + enter for help\n"); + +	if((vfd = open(videodev, O_RDWR | O_NONBLOCK)) < 0) { +		perror("open video device"); +		return 1; +	} +	if((afd = open(audiodev, O_RDWR | O_NONBLOCK)) < 0) { +		perror("open audio device"); +		return 1; +	} + +	while (process_kbd_input(vfd, afd) == 0) +		; + +	close(vfd); +	close(afd); +	return 0; +} + diff --git a/test/test_av_play.c b/test/test_av_play.c new file mode 100644 index 0000000..293d6d8 --- /dev/null +++ b/test/test_av_play.c @@ -0,0 +1,310 @@ +/* + * test_av_play.c - Test playing an MPEG A+V PES (e.g. VDR recordings) from a file. + * + * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> + *                    for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <linux/dvb/dmx.h> +#include <linux/dvb/video.h> +#include <linux/dvb/audio.h> +#include <sys/poll.h> + +static int audioPlay(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_PLAY) < 0)){ +		perror("AUDIO PLAY: "); +		return -1; +	} + +	return 0; +} + + +static int audioSelectSource(int fd, audio_stream_source_t source) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_SELECT_SOURCE, source) < 0)){ +		perror("AUDIO SELECT SOURCE: "); +		return -1; +	} + +	return 0; +} + + + +static int audioSetMute(int fd, int state) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_SET_MUTE, state) < 0)){ +		perror("AUDIO SET MUTE: "); +		return -1; +	} + +	return 0; +} + +static int audioSetAVSync(int fd, int state) +{ +	int ans; + +	if ( (ans = ioctl(fd,AUDIO_SET_AV_SYNC, state) < 0)){ +		perror("AUDIO SET AV SYNC: "); +		return -1; +	} + +	return 0; +} + +static int videoStop(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_STOP,0) < 0)){ +		perror("VIDEO STOP: "); +		return -1; +	} + +	return 0; +} + +static int videoPlay(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_PLAY) < 0)){ +		perror("VIDEO PLAY: "); +		return -1; +	} + +	return 0; +} + + +static int videoFreeze(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_FREEZE) < 0)){ +		perror("VIDEO FREEZE: "); +		return -1; +	} + +	return 0; +} + + +static int videoContinue(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_CONTINUE) < 0)){ +		perror("VIDEO CONTINUE: "); +		return -1; +	} + +	return 0; +} + +static int videoSelectSource(int fd, video_stream_source_t source) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_SELECT_SOURCE, source) < 0)){ +		perror("VIDEO SELECT SOURCE: "); +		return -1; +	} + +	return 0; +} + + +static int videoFastForward(int fd,int nframes) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes) < 0)){ +		perror("VIDEO FAST FORWARD: "); +		return -1; +	} + +	return 0; +} + +static int videoSlowMotion(int fd,int nframes) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_SLOWMOTION, nframes) < 0)){ +		perror("VIDEO SLOWMOTION: "); +		return -1; +	} + +	return 0; +} + +#define BUFFY 32768 +#define NFD   2 +static void play_file_av(int filefd, int vfd, int afd) +{ +	char buf[BUFFY]; +	int count; +	int written; +	struct pollfd pfd[NFD]; +	int stopped = 0; + +	pfd[0].fd = STDIN_FILENO; +	pfd[0].events = POLLIN; + +	pfd[1].fd = vfd; +	pfd[1].events = POLLOUT; + +	pfd[2].fd = afd; +	pfd[2].events = POLLOUT; + +	videoSelectSource(vfd,VIDEO_SOURCE_MEMORY); +	audioSelectSource(afd,AUDIO_SOURCE_MEMORY); + +	// FIXME: only seems to work if starting audio first! +	audioPlay(afd); +	videoPlay(vfd); + +	count = read(filefd,buf,BUFFY); +	write(vfd,buf,count); + +	while ( (count = read(filefd,buf,BUFFY)) >= 0  ){ +		written = 0; +		while(written < count){ +			if (poll(pfd,NFD,1)){ +				if (pfd[1].revents & POLLOUT){ +					written += write(vfd,buf+written, +							count-written); +				} +				if (pfd[0].revents & POLLIN){ +					int c = getchar(); +					switch(c){ +					case 'z': +						videoFreeze(vfd); +						printf("playback frozen\n"); +						stopped = 1; +						break; + +					case 's': +						videoStop(vfd); +						printf("playback stopped\n"); +						stopped = 1; +						break; + +					case 'c': +						videoContinue(vfd); +						printf("playback continued\n"); +						stopped = 0; +						break; + +					case 'p': +						videoPlay(vfd); +						audioPlay(afd); +					        audioSetAVSync(afd, 1); +						audioSetMute(afd, 0); +						printf("playback started\n"); +						stopped = 0; +						break; + +					case 'f': +					        audioSetAVSync(afd, 0); +						audioSetMute(afd, 1); +						videoFastForward(vfd,0); +						printf("fastforward\n"); +						stopped = 0; +						break; + +					case 'm': +					        audioSetAVSync(afd, 0); +						audioSetMute(afd, 1); +						videoSlowMotion(vfd,2); +						printf("slowmotion\n"); +						stopped = 0; +						break; + +					case 'q': +						videoContinue(vfd); +						exit(0); +						break; +					} +				} +			} +		} +	} +} + +int main(int argc, char **argv) +{ +	int vfd, afd; +	int filefd; +	char *videodev = "/dev/dvb/adapter0/video0"; +	char *audiodev = "/dev/dvb/adapter0/audio0"; + +	if (argc < 2) { +		fprintf(stderr, "usage: test_av_play mpeg_A+V_PES_file\n"); +		return 1; +	} + +	if (getenv("VIDEO")) +		videodev = getenv("VIDEO"); +	if (getenv("AUDIO")) +		videodev = getenv("AUDIO"); + +	printf("using video device '%s'\n", videodev); +	printf("using audio device '%s'\n", audiodev); + +	if ( (filefd = open(argv[1],O_RDONLY)) < 0){ +		perror("File open:"); +		return -1; +	} +	if((vfd = open(videodev,O_RDWR|O_NONBLOCK)) < 0){ +		perror("VIDEO DEVICE: "); +		return -1; +	} +	if((afd = open(audiodev,O_RDWR|O_NONBLOCK)) < 0){ +		perror("AUDIO DEVICE: "); +		return -1; +	} +	play_file_av(filefd, vfd, afd); +	close(vfd); +	close(afd); +	close(filefd); +	return 0; + + +} + diff --git a/test/test_dvr.c b/test/test_dvr.c new file mode 100644 index 0000000..4cee62f --- /dev/null +++ b/test/test_dvr.c @@ -0,0 +1,164 @@ +/* test_dvr.c - Test recording a TS from the dvr device. + * usage: test_dvr PID [more PIDs...] + * + * Copyright (C) 2003 convergence GmbH + * Johannes Stezenbach <js@convergence.de> + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +//hm, I haven't tested writing large files yet... maybe it works +#define _LARGEFILE64_SOURCE + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <inttypes.h> + +#include <linux/dvb/dmx.h> + +static unsigned long BUF_SIZE = 64 * 1024; +static unsigned long long total_bytes; + +static void usage(void) +{ +	fprintf(stderr, "usage: test_dvb file PID [more PIDs...]\n" +			"       record a partial TS stream consisting of TS packets\n" +			"       with the selected PIDs to the given file.\n" +			"       Use PID 0x2000 to record the full TS stream (if\n" +			"       the hardware supports it).\n" +			"       The demux and dvr devices used can be changed by setting\n" +			"       the environment variables DEMUX and DVR.\n" +			"       You can override the input buffer size by setting BUF_SIZE to\n" +			"       the number of bytes wanted.\n" +			"       Note: There is no output buffering, so writing to stdout is\n" +			"       not really supported, but you can try something like:\n" +			"       BUF_SIZE=188 ./test_dvr /dev/stdout 0 2>/dev/null | xxd\n" +			"       ./test_dvr /dev/stdout 0x100 0x110 2>/dev/null| xine stdin://mpeg2\n" +			"\n"); +	exit(1); +} + + +static void process_data(int dvrfd, int tsfd) +{ +	uint8_t buf[BUF_SIZE]; +	int bytes, b2; + +	bytes = read(dvrfd, buf, sizeof(buf)); +	if (bytes < 0) { +		perror("read"); +		if (errno == EOVERFLOW) +			return; +		fprintf(stderr, "exiting due to read() error\n"); +		exit(1); +	} +	total_bytes += bytes; +	b2 = write(tsfd, buf, bytes); +	if (b2 == -1) { +		perror("write"); +		exit(1); +	} else if (b2 < bytes) +		fprintf(stderr, "warning: read %d, but wrote only %d bytes\n", bytes, b2); +	else +		fprintf(stderr, "got %d bytes (%llu total)\n", bytes, total_bytes); +} + +static int add_filter(unsigned int pid, const unsigned char* dmxdev) +{ +	int fd; +	struct dmx_pes_filter_params f; + +	fd = open(dmxdev, O_RDONLY); +	if (fd == -1) { +		perror("cannot open demux device"); +		return 1; +	} + +	memset(&f, 0, sizeof(f)); +	f.pid = (uint16_t) pid; +	f.input = DMX_IN_FRONTEND; +	f.output = DMX_OUT_TS_TAP; +	f.pes_type = DMX_PES_OTHER; +	f.flags   = DMX_IMMEDIATE_START; + +	if (ioctl(fd, DMX_SET_PES_FILTER, &f) == -1) { +		perror("DMX_SET_PES_FILTER"); +		return 1; +	} +	fprintf(stderr, "set filter for PID 0x%04x on fd %d\n", pid, fd); + +	//FIXME: don't leak the fd +	return 0; +} + +int main(int argc, char *argv[]) +{ +	int dvrfd, tsfd; +	unsigned int pid; +	char *dmxdev = "/dev/dvb/adapter0/demux0"; +	char *dvrdev = "/dev/dvb/adapter0/dvr0"; +	int i; +	char *chkp; + +	if (argc < 3) +		usage(); + +	if (getenv("DEMUX")) +		dmxdev = getenv("DEMUX"); +	if (getenv("DVR")) +		dvrdev = getenv("DVR"); + +	fprintf(stderr, "using '%s' and '%s'\n" +		"writing to '%s'\n", dmxdev, dvrdev, argv[1]); +	tsfd = open(argv[1], O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, 0664); +	if (tsfd == -1) { +		perror("cannot write output file"); +		return 1; +	} + +	dvrfd = open(dvrdev, O_RDONLY); +	if (dvrfd == -1) { +		perror("cannot open dvr device"); +		return 1; +	} + +	if (getenv("BUF_SIZE") && ((BUF_SIZE = strtoul(getenv("BUF_SIZE"), NULL, 0)) > 0)) +		fprintf(stderr, "BUF_SIZE = %lu\n", BUF_SIZE); + +	for (i = 2; i < argc; i++) { +		pid = strtoul(argv[i], &chkp, 0); +		if (pid > 0x2000 || chkp == argv[i]) +			usage(); +		fprintf(stderr, "adding filter for PID 0x%04x\n", pid); +		//FIXME: stop & close filters later... +		if (add_filter(pid, dmxdev) != 0) +			return 1; +	} + +	for (;;) { +		process_data(dvrfd, tsfd); +	} + +	close(dvrfd); +	return 0; +} + diff --git a/test/test_dvr_play.c b/test/test_dvr_play.c new file mode 100644 index 0000000..af963d9 --- /dev/null +++ b/test/test_dvr_play.c @@ -0,0 +1,144 @@ +/* + * test_dvr_play.c - Play TS file via dvr device. + * + * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> + *                    for convergence integrated media GmbH + * Copyright (C) 2003 Convergence GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <sys/poll.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <stdlib.h> + +#include <linux/dvb/dmx.h> + + +#define BUFSIZE (512*188) + +void play_file_dvr(int filefd, int dvrfd) +{ +	char buf[BUFSIZE]; +	int count, written, bytes, total = 0; + +	while ((count = read(filefd, buf, BUFSIZE)) > 0) { +		total += count; +		fprintf(stderr, "read  %d (%d total)\n", count, total); +		written = 0; +		while (written < count) { +			bytes = write(dvrfd, buf + written, count - written); +			fprintf(stderr, "write %d\n", bytes); +			if (bytes < 0) { +				perror("write dvr"); +				return; +			} +			else if (bytes == 0) { +				fprintf(stderr, "write dvr: 0 bytes !"); +				return; +			} +			written += bytes; +		} +	} +} + +void set_pid(int fd, int pid, int type) +{ +	struct dmx_pes_filter_params pesFilterParams; + +	fprintf(stderr, "set PID 0x%04x (%d)\n", pid, type); +	if (ioctl(fd, DMX_STOP) < 0) +		perror("DMX STOP:"); + +	if (ioctl(fd, DMX_SET_BUFFER_SIZE, 64*1024) < 0) +		perror("DMX SET BUFFER:"); + +	pesFilterParams.pid = pid; +	pesFilterParams.input = DMX_IN_DVR; +	pesFilterParams.output = DMX_OUT_DECODER; +	pesFilterParams.pes_type = type; +	pesFilterParams.flags = DMX_IMMEDIATE_START; +	if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) +		perror("DMX SET FILTER"); +} + +int main(int argc, char **argv) +{ +	char *dmxdev = "/dev/dvb/adapter0/demux0"; +	char *dvrdev = "/dev/dvb/adapter0/dvr0"; +	int vpid, apid; +	int filefd, dvrfd, vfd, afd; + +	if (argc < 4) { +		fprintf(stderr, "usage: test_dvr_play TS-file video-PID audio-PID\n"); +		return 1; +	} +	vpid = strtoul(argv[2], NULL, 0); +	apid = strtoul(argv[3], NULL, 0); + +	filefd = open(argv[1], O_RDONLY); +	if (filefd == -1) { +		fprintf(stderr, "Failed to open '%s': %d %m\n", argv[1], errno); +		return 1; +	} + +	fprintf(stderr, "Playing '%s', video PID 0x%04x, audio PID 0x%04x\n", +			argv[1], vpid, apid); + +	if (getenv("DEMUX")) +		dmxdev = getenv("DEMUX"); +	if (getenv("DVR")) +		dvrdev = getenv("DVR"); + +	if ((dvrfd = open(dvrdev, O_WRONLY)) == -1) { +		fprintf(stderr, "Failed to open '%s': %d %m\n", dvrdev, errno); +		return 1; +	} + +	if ((vfd = open(dmxdev, O_WRONLY)) == -1) { +		fprintf(stderr, "Failed to open video '%s': %d %m\n", dmxdev, errno); +		return 1; +	} +	if ((afd = open(dmxdev, O_WRONLY)) == -1) { +		fprintf(stderr, "Failed to open audio '%s': %d %m\n", dmxdev, errno); +		return 1; +	} + +	/* playback timing is controlled via A/V PTS, so we cannot start +	 * writing to the DVR device before the PIDs are set... +	 */ +	set_pid(afd, apid, DMX_PES_AUDIO); +	set_pid(vfd, vpid, DMX_PES_VIDEO); + +	play_file_dvr(filefd, dvrfd); + +	close(dvrfd); +	close(afd); +	close(vfd); +	close(filefd); +	return 0; +} + diff --git a/test/test_front.c b/test/test_front.c new file mode 100644 index 0000000..1d08fc6 --- /dev/null +++ b/test/test_front.c @@ -0,0 +1,328 @@ +/*  + * test_front.c - Test program for new API + * + * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> +                      for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <ost/dmx.h> +#include <ost/frontend_old.h> +#include <ost/sec.h> +#include <ost/audio.h> +#include <sys/poll.h> + +int OSTSelftest(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,OST_SELFTEST,0) < 0)){ +		perror("OST SELF TEST: "); +		return -1; +	} + +	return 0; +} + +int OSTSetPowerState(int fd, uint32_t state) +{ +	int ans; + +	if ( (ans = ioctl(fd,OST_SET_POWER_STATE,state) < 0)){ +		perror("OST SET POWER STATE: "); +		return -1; +	} + +	return 0; +} + +int OSTGetPowerState(int fd, uint32_t *state) +{ +	int ans; + +	if ( (ans = ioctl(fd,OST_GET_POWER_STATE,state) < 0)){ +		perror("OST GET POWER STATE: "); +		return -1; +	} + +	switch(*state){ +	case OST_POWER_ON: +		printf("POWER ON (%d)\n",*state); +		break; +	case OST_POWER_STANDBY: +		printf("POWER STANDBY (%d)\n",*state); +		break; +	case OST_POWER_SUSPEND: +		printf("POWER SUSPEND (%d)\n",*state); +		break; +	case OST_POWER_OFF: +		printf("POWER OFF (%d)\n",*state); +		break; +	default: +		printf("unknown (%d)\n",*state); +		break; +	} + +	return 0; +} + +int FEReadStatus(int fd) +{ +	int ans; +	feStatus stat; + +	if ( (ans = ioctl(fd,FE_READ_STATUS,&stat) < 0)){ +		perror("FE READ STATUS: "); +		return -1; +	} + +	if (stat & FE_HAS_POWER) +		printf("FE HAS POWER\n"); + +	if (stat & FE_HAS_SIGNAL) +		printf("FE HAS SIGNAL\n"); + +	if (stat & QPSK_SPECTRUM_INV) +		printf("QPSK SPEKTRUM INV\n"); + +	return 0; +} + +int FEReadBER(int fd, uint32_t *ber) +{ +	int ans; + +	if ( (ans = ioctl(fd,FE_READ_BER, ber) < 0)){ +		perror("FE READ_BER: "); +		return -1; +	} +	printf("BER: %d\n",*ber); + +	return 0; +} + +int FEReadSignalStrength(int fd, int32_t *strength) +{ +	int ans; + +	if ( (ans = ioctl(fd,FE_READ_SIGNAL_STRENGTH, strength) < 0)){ +		perror("FE READ SIGNAL STRENGTH: "); +		return -1; +	} +	printf("SIGNAL STRENGTH: %d\n",*strength); + +	return 0; +} + +int FEReadSNR(int fd, int32_t *snr) +{ +	int ans; + +	if ( (ans = ioctl(fd,FE_READ_SNR, snr) < 0)){ +		perror("FE READ_SNR: "); +		return -1; +	} +	printf("SNR: %d\n",*snr); + +	return 0; +} + + +int FEReadUncorrectedBlocks(int fd, uint32_t *ucb) +{ +	int ans; + +	if ( (ans = ioctl(fd,FE_READ_UNCORRECTED_BLOCKS, ucb) < 0)){ +		perror("FE READ UNCORRECTED BLOCKS: "); +		return -1; +	} +	printf("UBLOCKS: %d\n",*ucb); + +	return 0; +} + +int FEGetNextFrequency(int fd, uint32_t *nfr) +{ +	int ans; + +	if ( (ans = ioctl(fd,FE_GET_NEXT_FREQUENCY, nfr) < 0)){ +		perror("FE GET NEXT FREQUENCY: "); +		return -1; +	} +	printf("Next Frequency: %d\n",*nfr); + +	return 0; +} + +int FEGetNextSymbolRate(int fd, uint32_t *nsr) +{ +	int ans; + +	if ( (ans = ioctl(fd,FE_GET_NEXT_SYMBOL_RATE, nsr) < 0)){ +		perror("FE GET NEXT SYMBOL RATE: "); +		return -1; +	} +	printf("Next Symbol Rate: %d\n",*nsr); + +	return 0; +} + +int QPSKTune(int fd, struct qpskParameters *param) +{ +	int ans; + +	if ( (ans = ioctl(fd,QPSK_TUNE, param) < 0)){ +		perror("QPSK TUNE: "); +		return -1; +	} + +	return 0; +} + +int QPSKGetEvent (int fd, struct qpskEvent *event) +{ +	int ans; + +	if ( (ans = ioctl(fd,QPSK_GET_EVENT, event) < 0)){ +		perror("QPSK GET EVENT: "); +		return -1; +	} + +	return 0; +} + +int QPSKFEInfo (int fd, struct qpskFrontendInfo *info) +{ +	int ans; + +	if ( (ans = ioctl(fd,QPSK_FE_INFO, info) < 0)){ +		perror("QPSK FE INFO: "); +		return -1; +	} + +	printf("min Frequency   : %d\n", info->minFrequency); +	printf("max Frequency   : %d\n", info->maxFrequency); +	printf("min Symbol Rate : %d\n", info->minSymbolRate); +	printf("max Symbol Rate : %d\n", info->maxSymbolRate); +	printf("Hardware Type   : %d\n", info->hwType); +	printf("Hardware Version: %d\n", info->hwVersion); + +	return 0; +} + +int SecGetStatus (int fd, struct secStatus *state) +{ +	int ans; + +	if ( (ans = ioctl(fd,SEC_GET_STATUS, state) < 0)){ +		perror("QPSK GET EVENT: "); +		return -1; +	} + +	switch (state->busMode){ +	case SEC_BUS_IDLE: +		printf("SEC BUS MODE:  IDLE (%d)\n",state->busMode); +		break; +	case SEC_BUS_BUSY: +		printf("SEC BUS MODE:  BUSY (%d)\n",state->busMode); +		break; +	case SEC_BUS_OFF: +		printf("SEC BUS MODE:  OFF  (%d)\n",state->busMode); +		break; +	case SEC_BUS_OVERLOAD: +		printf("SEC BUS MODE:  OVERLOAD (%d)\n",state->busMode); +		break; +	default: +		printf("SEC BUS MODE:  unknown  (%d)\n",state->busMode); +		break; +	} + +	 +	switch (state->selVolt){ +	case SEC_VOLTAGE_OFF: +		printf("SEC VOLTAGE:  OFF (%d)\n",state->selVolt); +		break; +	case SEC_VOLTAGE_LT: +		printf("SEC VOLTAGE:  LT  (%d)\n",state->selVolt); +		break; +	case SEC_VOLTAGE_13: +		printf("SEC VOLTAGE:  13  (%d)\n",state->selVolt); +		break; +	case SEC_VOLTAGE_13_5: +		printf("SEC VOLTAGE:  13.5 (%d)\n",state->selVolt); +		break; +	case SEC_VOLTAGE_18: +		printf("SEC VOLTAGE:  18 (%d)\n",state->selVolt); +		break; +	case SEC_VOLTAGE_18_5: +		printf("SEC VOLTAGE:  18.5 (%d)\n",state->selVolt); +		break; +	default: +		printf("SEC VOLTAGE:  unknown (%d)\n",state->selVolt); +		break; +	} + +	printf("SEC CONT TONE: %s\n", (state->contTone ? "ON" : "OFF")); +	return 0; +} + + +main(int argc, char **argv) +{ +	int fd,fd_sec; +	uint32_t state; +	int32_t strength; +	struct qpskFrontendInfo info; +	struct secStatus sec_state; + +	if((fd = open("/dev/ost/qpskfe",O_RDWR)) < 0){ +		perror("FRONTEND DEVICE: "); +		return -1; +	} +	if((fd_sec = open("/dev/ost/sec",O_RDWR)) < 0){ +		perror("SEC DEVICE: "); +		return -1; +	} + +	OSTSelftest(fd); +	OSTSetPowerState(fd, OST_POWER_ON); +	OSTGetPowerState(fd, &state); +	FEReadStatus(fd); +	FEReadBER(fd, &state); +	FEReadSignalStrength(fd, &strength); +	FEReadSNR(fd, &state); +	FEReadUncorrectedBlocks(fd, &state); +	state = 12567000; +	FEGetNextFrequency(fd, &state); +	FEGetNextSymbolRate(fd, &state); +	QPSKFEInfo (fd, &info); +	SecGetStatus (fd_sec, &sec_state); + +	close(fd); +	close(fd_sec); +} + diff --git a/test/test_pes.c b/test/test_pes.c new file mode 100644 index 0000000..bd5a53e --- /dev/null +++ b/test/test_pes.c @@ -0,0 +1,137 @@ +/* test_pes.c - Test for PES filters. + * usage: DEMUX=/dev/dvb/adapterX/demuxX test_pes PID + * + * Copyright (C) 2002 convergence GmbH + * Johannes Stezenbach <js@convergence.de> + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include <linux/dvb/dmx.h> + +#include "hex_dump.h" + +#define MAX_PES_SIZE (4*1024) + + +void usage(void) +{ +	fprintf(stderr, "usage: test_pes PID [filename]\n"); +	fprintf(stderr, "       Print a hexdump of PES packets from PID to stdout.\n"); +	fprintf(stderr, "  filename : Write binary PES data to file (no hexdump).\n"); +	fprintf(stderr, "       The default demux device used can be changed\n"); +	fprintf(stderr, "       using the DEMUX environment variable\n"); +	exit(1); +} + +void process_pes(int fd, FILE *out) +{ +	uint8_t buf[MAX_PES_SIZE]; +	int bytes; + +	bytes = read(fd, buf, sizeof(buf)); +	if (bytes < 0) { +		if (errno == EOVERFLOW) { +			fprintf(stderr, "read error: buffer overflow (%d)\n", +					EOVERFLOW); +			return; +		} +		else { +			perror("read"); +			exit(1); +		} +	} +	if (out == stdout) { +		hex_dump(buf, bytes); +		printf("\n"); +	} +	else { +		printf("got %d bytes\n", bytes); +		if (fwrite(buf, 1, bytes, out) == 0) +			perror("write output"); +	} +} + +int set_filter(int fd, unsigned int pid) +{ +	struct dmx_pes_filter_params f; + +	f.pid = (uint16_t) pid; +	f.input = DMX_IN_FRONTEND; +	f.output = DMX_OUT_TAP; +	f.pes_type = DMX_PES_OTHER; +	f.flags = DMX_IMMEDIATE_START; +	if (ioctl(fd, DMX_SET_PES_FILTER, &f) == -1) { +		perror("ioctl DMX_SET_PES_FILTER"); +		return 1; +	} +	return 0; +} + + +int main(int argc, char *argv[]) +{ +	int dmxfd; +	unsigned long pid; +	char *dmxdev = "/dev/dvb/adapter0/demux0"; +	FILE *out = stdout; + +	if (argc != 2 && argc != 3) +		usage(); + +	pid = strtoul(argv[1], NULL, 0); +	if (pid > 0x1fff) +		usage(); +	if (getenv("DEMUX")) +		dmxdev = getenv("DEMUX"); + +	fprintf(stderr, "test_pes: using '%s'\n", dmxdev); +	fprintf(stderr, "          PID 0x%04lx\n", pid); + +	if (argc == 3) { +		out = fopen(argv[2], "wb"); +		if (!out) { +			perror("open output file"); +			exit(1); +		} +		fprintf(stderr, "          output to '%s'\n", argv[2]); +	} + +	if ((dmxfd = open(dmxdev, O_RDWR)) < 0){ +		perror("open"); +		return 1; +	} + +	if (set_filter(dmxfd, pid) != 0) +		return 1; + +	for (;;) { +		process_pes(dmxfd, out); +	} + +	close(dmxfd); +	return 0; +} diff --git a/test/test_sec_ne.c b/test/test_sec_ne.c new file mode 100644 index 0000000..9fcc8b3 --- /dev/null +++ b/test/test_sec_ne.c @@ -0,0 +1,165 @@ +/* test_sec_ne.c - Test for Not-Equal section filters. + * usage: DEMUX=/dev/dvb/adapterX/demuxX test_sec_ne pid [tid [tid_ext]] + * + * Copyright (C) 2002 convergence GmbH + * Johannes Stezenbach <js@convergence.de> + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include <linux/dvb/dmx.h> + +#include "hex_dump.h" + +#define MAX_SECTION_SIZE 8192 + +static unsigned int version_number; + +void usage(void) +{ +	fprintf(stderr, "usage: test_sec_ne pid [tid [tid_ext]]\n"); +	fprintf(stderr, "       Read the version_number from the first section\n"); +	fprintf(stderr, "       and sec a filter to wait for it to change.\n"); +	fprintf(stderr, "       The default demux device used can be changed\n"); +	fprintf(stderr, "       using the DEMUX environment variable;\n"); +	exit(1); +} + + +void process_section(int fd) +{ +	uint8_t buf[MAX_SECTION_SIZE]; +	int bytes; + +	bytes = read(fd, buf, sizeof(buf)); +	if (bytes < 0) { +		perror("read"); +		if (bytes != ETIMEDOUT) +			exit(1); +	} +	hex_dump(buf, bytes); +	version_number = ((buf[5] >> 1) & 0x1f); +	printf("current version_number: %u\n\n", version_number); +} + +int set_filter(int fd, unsigned int pid, unsigned int tid, +		unsigned int tid_ext, unsigned int version_number) +{ +	struct dmx_sct_filter_params f; +	unsigned long bufsz; + +	if (getenv("BUFFER")) { +		bufsz=strtoul(getenv("BUFFER"), NULL, 0); +		if (bufsz > 0 && bufsz <= MAX_SECTION_SIZE) { +			fprintf(stderr, "DMX_SET_BUFFER_SIZE %lu\n", bufsz); +			if (ioctl(fd, DMX_SET_BUFFER_SIZE, bufsz) == -1) { +				perror("DMX_SET_BUFFER_SIZE"); +				return 1; +			} +		} +	} +	memset(&f.filter, 0, sizeof(struct dmx_filter)); +	f.pid = (uint16_t) pid; +	if (tid < 0x100) { +		f.filter.filter[0] = (uint8_t) tid; +		f.filter.mask[0]   = 0xff; +	} +	if (tid_ext < 0x10000) { +		f.filter.filter[1] = (uint8_t) (tid_ext >> 8); +		f.filter.filter[2] = (uint8_t) (tid_ext & 0xff); +		f.filter.mask[1]   = 0xff; +		f.filter.mask[2]   = 0xff; +	} +	if (version_number < 0x20) { +		f.filter.filter[3] = (uint8_t) (version_number << 1); +		f.filter.mask[3]   = 0x3e; +		f.filter.mode[3]   = 0x3e; +	} +	f.timeout = 0; +	f.flags = DMX_IMMEDIATE_START; + +	if (ioctl(fd, DMX_SET_FILTER, &f) == -1) { +		perror("DMX_SET_FILTER"); +		return 1; +	} +	return 0; +} + + +int main(int argc, char *argv[]) +{ +	int dmxfd; +	unsigned long pid, tid, tid_ext; +	char * dmxdev = "/dev/dvb/adapter0/demux0"; + +	if (argc < 2 || argc > 4) +		usage(); + +	pid = strtoul(argv[1], NULL, 0); +	if (pid > 0x1fff) +		usage(); +	if (argc > 2) { +		tid = strtoul(argv[2], NULL, 0); +		if (tid > 0xff) +			usage(); +	} else +		tid = 0x100; +	if (argc > 3) { +		tid_ext = strtoul(argv[3], NULL, 0); +		if (tid_ext > 0xffff) +			usage(); +	} else +		tid_ext = 0x10000; + +	if (getenv("DEMUX")) +		dmxdev = getenv("DEMUX"); +	fprintf(stderr, "test_sec_ne: using '%s'\n", dmxdev); +	fprintf(stderr, "             PID 0x%04lx\n", pid); +	if (tid < 0x100) +		fprintf(stderr, "               TID 0x%02lx\n", tid); +	if (tid_ext < 0x10000) +		fprintf(stderr, "               TID EXT 0x%04lx\n", tid_ext); + +	if ((dmxfd = open(dmxdev, O_RDWR)) < 0){ +		perror("open"); +		return 1; +	} + +	if (set_filter(dmxfd, pid, tid, tid_ext, 0xff) != 0) +		return 1; +	process_section(dmxfd); +	while (1) { +		if (set_filter(dmxfd, pid, tid, tid_ext, version_number) != 0) +			return 1; +		process_section(dmxfd); +	} +	for (;;) { +		process_section(dmxfd); +	} + +	close(dmxfd); +	return 0; +} + diff --git a/test/test_sections.c b/test/test_sections.c new file mode 100644 index 0000000..d567db0 --- /dev/null +++ b/test/test_sections.c @@ -0,0 +1,197 @@ +/* test_sections.c - Test for section filters. + * usage: DEMUX=/dev/dvb/adapterX/demuxX test_sections [PID [TID]] + * + * Copyright (C) 2002 convergence GmbH + * Johannes Stezenbach <js@convergence.de> + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include <linux/dvb/dmx.h> + +#include "hex_dump.h" + +#define MAX_SECTION_SIZE 8192 + + +#if !defined(DMX_FILTER_SIZE) +#define DMX_FILTER_SIZE 16 +#endif + +static void parse_filter(unsigned char* filter, const char* filter_desc) +{ +        int filter_idx; +        char* end_ptr; + +        memset(filter, '\0', DMX_FILTER_SIZE); + +        for (filter_idx = 1; /* Leave first byte for tid */ +             filter_idx < DMX_FILTER_SIZE-1; ++filter_idx) { +                filter[filter_idx] = strtoul(filter_desc, &end_ptr, 0); + +                if (*end_ptr == '\0' || end_ptr == filter_desc) +                        break; + +                filter_desc = end_ptr; +        } +} + +void usage(void) +{ +	fprintf(stderr, "usage: test_sections PID [TID] [FILTER] [MASK]\n"); +	fprintf(stderr, "       The default demux device used can be changed\n"); +	fprintf(stderr, "       using the DEMUX environment variable;\n"); +	fprintf(stderr, "       set env BUFFER to play with DMX_SET_BUFFER_SIZE\n"); +        fprintf(stderr, "\n"); +        fprintf(stderr, "       The optional filter and mask may be used to filter on\n"); +        fprintf(stderr, "       additional bytes. These bytes may be given in hex or dec\n"); +        fprintf(stderr, "       separated by spaces (hint: you may have to use quotes around\n"); +        fprintf(stderr, "       FILTER and MASK). TID is always the first byte of the filter,\n"); +        fprintf(stderr, "       and the first byte from FILTER applies to byte 3 of the section\n"); +        fprintf(stderr, "       data (i.e. the first byte after the section length)\n"); +	exit(1); +} + + +void process_section(int fd) +{ +	uint8_t buf[MAX_SECTION_SIZE]; +	int bytes; + +	bytes = read(fd, buf, sizeof(buf)); +	if (bytes < 0) { +		perror("read"); +		if (errno != EOVERFLOW) +			exit(1); +	} +	hex_dump(buf, bytes); +	printf("\n"); +} + +int set_filter(int fd, unsigned int pid, +               const unsigned char* filter, const unsigned char* mask) +{ +	struct dmx_sct_filter_params f; +	unsigned long bufsz; + +	if (getenv("BUFFER")) { +		bufsz=strtoul(getenv("BUFFER"), NULL, 0); +		if (bufsz > 0 && bufsz <= MAX_SECTION_SIZE) { +			fprintf(stderr, "DMX_SET_BUFFER_SIZE %lu\n", bufsz); +			if (ioctl(fd, DMX_SET_BUFFER_SIZE, bufsz) == -1) { +				perror("DMX_SET_BUFFER_SIZE"); +				return 1; +			} +		} +	} +	memset(&f.filter, 0, sizeof(struct dmx_filter)); +	f.pid = (uint16_t) pid; + +        memcpy(f.filter.filter, filter, DMX_FILTER_SIZE); +        memcpy(f.filter.mask, mask, DMX_FILTER_SIZE); +	f.timeout = 0; +	f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC; + +	if (ioctl(fd, DMX_SET_FILTER, &f) == -1) { +		perror("DMX_SET_FILTER"); +		return 1; +	} +	return 0; +} + +int main(int argc, char *argv[]) +{ +	int dmxfd; +	unsigned long pid, tid; +	char * dmxdev = "/dev/dvb/adapter0/demux0"; +        unsigned char filter[DMX_FILTER_SIZE]; +        unsigned char mask[DMX_FILTER_SIZE]; +        int filter_idx; + +	if (argc < 2 || argc > 5) +		usage(); + +	pid = strtoul(argv[1], NULL, 0); +	if (pid > 0x1fff) +		usage(); +	if (argc > 2) { +		tid = strtoul(argv[2], NULL, 0); +		if (tid > 0xff) +			usage(); +	} else +		tid = 0x100; + +        if (argc > 3) +                parse_filter(filter, argv[3]); +        else +                memset(filter, '\0', sizeof(filter)); + +        if (argc > 4) +                parse_filter(mask, argv[4]); +        else +                memset(mask, '\0', sizeof(mask)); + +        if (tid < 0x100) { +                filter[0] = tid; +                mask[0]   = 0xff; +        } + +	if (getenv("DEMUX")) +		dmxdev = getenv("DEMUX"); +	fprintf(stderr, "test_sections: using '%s'\n", dmxdev); +	fprintf(stderr, "  PID 0x%04lx\n", pid); +	if (tid < 0x100) +		fprintf(stderr, "  TID 0x%02lx\n", tid); + + +        fprintf(stderr, "  Filter "); + +        for (filter_idx = 0; filter_idx < DMX_FILTER_SIZE; ++filter_idx) +                fprintf(stderr, "0x%.2x ", filter[filter_idx]); +        fprintf(stderr, "\n"); + +        fprintf(stderr, "    Mask "); + +        for (filter_idx = 0; filter_idx < DMX_FILTER_SIZE; ++filter_idx) +                fprintf(stderr, "0x%.2x ", mask[filter_idx]); + +        fprintf(stderr, "\n"); +         +	if ((dmxfd = open(dmxdev, O_RDWR)) < 0){ +		perror("open"); +		return 1; +	} + +	if (set_filter(dmxfd, pid, filter, mask) != 0) +		return 1; + +	for (;;) { +		process_section(dmxfd); +	} + +	close(dmxfd); +	return 0; +} + diff --git a/test/test_stc.c b/test/test_stc.c new file mode 100644 index 0000000..89f141d --- /dev/null +++ b/test/test_stc.c @@ -0,0 +1,74 @@ +/* test_stc.c - Test for DMX_GET_STC. + * usage: DEMUX=/dev/dvb/adapterX/demuxX test_stc + * + * Copyright (C) 2003 convergence GmbH + * Johannes Stezenbach <js@convergence.de> + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include <linux/dvb/dmx.h> + + +void usage(void) +{ +	fprintf(stderr, "usage: test_stc\n"); +	fprintf(stderr, "       The default demux device used can be changed\n"); +	fprintf(stderr, "       using the DEMUX environment variable;\n"); +        fprintf(stderr, "\n"); +	exit(1); +} + + +int main(int argc, char *argv[]) +{ +	int dmxfd; +	char * dmxdev = "/dev/dvb/adapter0/demux0"; +	struct dmx_stc stc; + +	if (argc != 1 || argv[1]) +		usage(); + +	if (getenv("DEMUX")) +		dmxdev = getenv("DEMUX"); +	fprintf(stderr, "test_stc: using '%s'\n", dmxdev); + +	if ((dmxfd = open(dmxdev, O_RDWR)) < 0) { +		perror("open"); +		return 1; +	} + +	stc.num = 0; +	if (ioctl(dmxfd, DMX_GET_STC, &stc) == -1) { +		perror("DMX_GET_STC"); +		return 1; +	} + +	printf("STC = %llu (%llu / %u)\n", stc.stc / stc.base, stc.stc, stc.base); + +	close(dmxfd); +	return 0; +} + diff --git a/test/test_stillimage.c b/test/test_stillimage.c new file mode 100644 index 0000000..264b2c4 --- /dev/null +++ b/test/test_stillimage.c @@ -0,0 +1,103 @@ +/* display single iframes as stillimages + * iframes can be created with the 'convert' tool from imagemagick + * and mpeg2encode from ftp.mpeg.org, and must have a supported + * size, e.g. 702x576: + *   $ convert -sample 702x576\! test.jpg test.mpg + * + * or more advanced using netpbm and mpeg2enc (not mpeg2encode) : + *   $ cat image.jpg | jpegtopnm | pnmscale -xsize=704 -ysize=576 |\ + *      ppmntsc --pal | ppmtoy4m  -F 25:1 -A 4:3 |\ + *      mpeg2enc -f 7 -T 90 -F 3 -np -a 2 -o "image.mpg" + * + */ + +#include <sys/ioctl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <linux/dvb/video.h> + + +static const char *usage_string = "\n\t" +	"usage: %s <still.mpg> [still.mpg ...]\n" +	"\n\t" +	"to use another videodev than the first, set the environment variable VIDEODEV\n\t" +	"e.g.[user@linux]$ export VIDEODEV=\"/dev/dvb/adapter1/video1\".\n\t" +	"to display the image <n> seconds, instead of 10, set the variable SSTIME\n\t" +	"e.g. [user@linux]$ export SSTIME=\"60\" to display the still for 1 minute.\n\t" +	"this options can be set in the same line as the %s command:\n\t" +	"e.g. $ SSTIME=25 VIDEODEV=/dev/dvb/adapter1/video1 %s ...\n"; + + +int main (int argc, char **argv) +{ +	int fd; +	int filefd; +	struct stat st; +	struct video_still_picture sp; +	char *videodev = "/dev/dvb/adapter0/video0"; +	char *env_sstime; +	int i = 1; +	int tsec = 10; + +	if (argc < 2) { +		fprintf (stderr, usage_string, argv[0],argv[0],argv[0]); +		return -1; +	} + +	if (getenv ("VIDEODEV")) +		videodev = getenv("VIDEODEV"); + +	if (getenv ("SSTIME")) { +		env_sstime = getenv("SSTIME"); +		tsec = atoi(env_sstime); +	} + +	if ((fd = open(videodev, O_RDWR)) < 0) { +		perror(videodev); +		return -1; +	} + +next_pic: +	printf("I-frame     : '%s'\n", argv[i]); +	if ((filefd = open(argv[i], O_RDONLY)) < 0) { +		perror(argv[i]); +		return -1; +	} + +	fstat(filefd, &st); + +	sp.iFrame = (char *) malloc (st.st_size); +	sp.size = st.st_size; +	printf("I-frame size: %d\n", sp.size); + +	if (!sp.iFrame) { +		fprintf (stderr, "No memory for I-Frame\n"); +		return -1; +	} + +	printf ("read: %d bytes\n", read(filefd, sp.iFrame, sp.size)); +	close(filefd); + +	if ((ioctl(fd, VIDEO_STILLPICTURE, &sp) < 0)) { +		perror("ioctl VIDEO_STILLPICTURE"); +		return -1; +	} +	free(sp.iFrame); + +	printf("Display image %d seconds ...\n",tsec); +	sleep(tsec); +	printf("Done.\n"); +	if (argc > ++i) +		goto next_pic; + +	return 0; +} + + diff --git a/test/test_switch.c b/test/test_switch.c new file mode 100644 index 0000000..7f80891 --- /dev/null +++ b/test/test_switch.c @@ -0,0 +1,355 @@ +/*  + * test_switch.c - Test program for new API + * + * Copyright (C) 2001 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> +                      for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <sys/poll.h> + +#include <linux/dvb/dmx.h> +#include <linux/dvb/frontend_old.h> +#include <linux/dvb/sec.h> +#include <linux/dvb/video.h> + +int fd_frontend; +int fd_sec; +int fd_demuxa; +int fd_demuxv; +int fd_demuxtt; + +struct dmx_sct_filter_params sctFilterParams; +	 +struct secCommand scmd; +struct secCmdSequence scmds; +struct dmx_pes_filter_params pesFilterParams;  +struct dmx_pes_filter_params pesFilterParamsV;  +struct dmx_pes_filter_params pesFilterParamsA;  +struct dmx_pes_filter_params pesFilterParamsTT;  +FrontendParameters frp; +int front_type; + + +set_front(void)  +{ +	fe_status_t stat = 0; +	int i, freq; +	uint32_t soff; +	   +	scmds.miniCommand = SEC_MINI_NONE; +	scmds.numCommands = 1; +	scmds.commands = &scmd; +	 +	soff = frp.u.qpsk.SymbolRate/16000; + +	if (ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds) < 0) +		perror("setfront sec"); +	usleep(100000); +		 +	freq = frp.Frequency; +		 +	while(tune_it(&frp)); +}	         + +set_diseqc_nb(int nr)  +{ +	scmd.type=0; +	scmd.u.diseqc.addr = 0x10; +	scmd.u.diseqc.cmd = 0x38; +	scmd.u.diseqc.numParams = 1; +	scmd.u.diseqc.params[0] = 0xF0 | ((nr * 4) & 0x0F) |  +	  (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) | +	  (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0); +} + +set_ttpid(ushort ttpid)  +{   +        if (ttpid==0 || ttpid==0xffff || ttpid==0x1fff) { +	        ioctl(fd_demuxtt, DMX_STOP, 0); +	        return; +	} + +	pesFilterParamsTT.pid     = ttpid; +	pesFilterParamsTT.input   = DMX_IN_FRONTEND;  +	pesFilterParamsTT.output  = DMX_OUT_DECODER;  +	pesFilterParamsTT.pes_type = DMX_PES_TELETEXT;  +	pesFilterParamsTT.flags   = DMX_IMMEDIATE_START; +	if (ioctl(fd_demuxtt, DMX_SET_PES_FILTER,  +		  &pesFilterParamsTT) < 0) { +	  printf("PID=%04x\n", ttpid); +		perror("set_ttpid"); +	} +} + +set_vpid(ushort vpid)  +{   +        if (vpid==0 || vpid==0xffff || vpid==0x1fff) { +	        ioctl(fd_demuxv, DMX_STOP, 0); +	        return; +	} + +	pesFilterParamsV.pid     = vpid; +	pesFilterParamsV.input   = DMX_IN_FRONTEND;  +	pesFilterParamsV.output  = DMX_OUT_DECODER;  +	pesFilterParamsV.pes_type = DMX_PES_VIDEO;  +	pesFilterParamsV.flags   = DMX_IMMEDIATE_START; +	if (ioctl(fd_demuxv, DMX_SET_PES_FILTER,  +		  &pesFilterParamsV) < 0) +		perror("set_vpid"); +} + +set_apid(ushort apid)  +{   +        if (apid==0 || apid==0xffff || apid==0x1fff) { +	        ioctl(fd_demuxa, DMX_STOP, apid); +	        return; +	} +	pesFilterParamsA.pid = apid; +	pesFilterParamsA.input = DMX_IN_FRONTEND;  +	pesFilterParamsA.output = DMX_OUT_DECODER;  +	pesFilterParamsA.pes_type = DMX_PES_AUDIO;  +	pesFilterParamsA.flags = DMX_IMMEDIATE_START; +	if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,  +		  &pesFilterParamsA) < 0) +		perror("set_apid"); +} + +int tune_it(FrontendParameters *frp) +{ +	fe_status_t stat = 0; +	int res; +	FrontendEvent event; +	int count = 0; +	struct pollfd pfd[1]; + +	if (ioctl(fd_frontend, FE_SET_FRONTEND, frp) <0) +		perror("setfront front"); + + + +	pfd[0].fd = fd_frontend; +	pfd[0].events = POLLIN; + +	if (poll(pfd,1,3000)){ +		if (pfd[0].revents & POLLIN){ +			printf("Getting QPSK event\n"); +			if ( ioctl(fd_frontend, FE_GET_EVENT, &event)   + +			     == -EOVERFLOW){ +				perror("qpsk get event"); +				return -1; +			} +			printf("Received "); +			switch(event.type){ +			case FE_UNEXPECTED_EV: +				printf("unexpected event\n"); +				return -1; +			case FE_FAILURE_EV: +				printf("failure event\n"); +				return -1; +				 +			case FE_COMPLETION_EV: +				printf("completion event\n"); +			} +		} +	} +	return 0; +} + +set_tp(uint *freq, int ttk, int pol, uint srate, int dis)  +{ +	if (*freq < 11700000) { +		frp.Frequency = (*freq - 9750000); +		scmds.continuousTone = SEC_TONE_OFF; +	} else { +		frp.Frequency = (*freq - 10600000); +		scmds.continuousTone = SEC_TONE_ON; +	} +	if (pol) scmds.voltage = SEC_VOLTAGE_18; +	else scmds.voltage = SEC_VOLTAGE_13; +	set_diseqc_nb(dis); +	frp.u.qpsk.SymbolRate = srate; +	frp.u.qpsk.FEC_inner = 0; +} + +get_front(void)  +{ +	set_vpid(0); +	set_apid(0); +	set_ttpid(0); +	scmds.voltage = SEC_VOLTAGE_18;  +	scmds.miniCommand = SEC_MINI_NONE; +	scmds.continuousTone = SEC_TONE_OFF; +	scmds.numCommands=1; +	scmds.commands=&scmd; +	 +	frp.Frequency=(12073000-10600000); +	frp.u.qpsk.SymbolRate=25378000; +	frp.u.qpsk.FEC_inner=(fe_code_rate_t)5; +}	         +   + +void get_sect(int fd) +{ +        u_char sec[4096]; +        int len, i; +        uint16_t cpid = 0; +        uint16_t length; +        struct pollfd pfd; +        +        pfd.fd = fd; +        pfd.events = POLLIN; +        +	while (1){ +		if (poll(&pfd, 1, 5000) != POLLIN) { +			printf("not found\n"); +			printf("Timeout\n"); +		} else { +			len = read(fd, sec, 4096); + +			length  = (sec[1]& 0x0F)<<8; +			length |= (sec[2]& 0xFF); +         + +			for (i= 0; i < length+3; i++) { +				printf("0x%02x ",sec[i]); +				if ( !((i+1)%8)) +					printf("\n"); +			} +			printf("\n"); +		} +	} +} + +int FEReadStatus(int fd, fe_status_t *stat) +{ +	int ans; + +	if ( (ans = ioctl(fd,FE_READ_STATUS,stat) < 0)){ +		perror("FE READ STATUS: "); +		return -1; +	} + +	if (*stat & FE_HAS_POWER) +		printf("FE HAS POWER\n"); + +	if (*stat & FE_HAS_SIGNAL) +		printf("FE HAS SIGNAL\n"); + +	if (*stat & FE_SPECTRUM_INV) +		printf("QPSK SPEKTRUM INV\n"); + +	return 0; +} + +int has_signal() +{ +	fe_status_t stat; +	 +	FEReadStatus(fd_frontend, &stat); +	if (stat & FE_HAS_SIGNAL) +		return 1; +	else { +		printf("Tuning failed\n"); +		return 0; +	} +} + +main() +{ +	int freq; + +	fd_demuxtt = open("/dev/ost/demux", O_RDWR|O_NONBLOCK); +	fd_frontend = open("/dev/ost/frontend", O_RDWR); +	fd_sec = open("/dev/ost/sec", O_RDWR); +	fd_demuxa = open("/dev/ost/demux", O_RDWR|O_NONBLOCK); +	fd_demuxv = open("/dev/ost/demux", O_RDWR|O_NONBLOCK); + +//	get_front(); +//        set_vpid(0x7d0); +//       set_apid(0x7d2); +//	set_ttpid(0); +//	freq = 12073000; +//	set_tp(&freq, 1, 1, 25378000, 3); +//	set_diseqc_nb(dis); + +	scmds.voltage = SEC_VOLTAGE_18; +//	scmds.voltage = SEC_VOLTAGE_13; +	scmds.miniCommand = SEC_MINI_NONE; +	scmds.continuousTone = SEC_TONE_OFF; +	scmds.numCommands=1; +	scmds.commands=&scmd; +	frp.Frequency = (12073000 - 10600000); +//	frp.Frequency = (11975000 - 10600000); +	scmds.continuousTone = SEC_TONE_ON;  +	frp.u.qpsk.SymbolRate = 25378000; +//	frp.u.qpsk.SymbolRate = 27500000; +//	frp.u.qpsk.FEC_inner = FEC_AUTO; +	frp.u.qpsk.FEC_inner = (fe_code_rate_t)5; +	scmd.type=0; +	scmd.u.diseqc.addr = 0x10; +	scmd.u.diseqc.cmd = 0x38; +	scmd.u.diseqc.numParams = 1; +	scmd.u.diseqc.params[0] = 0xF0 | ((3 * 4) & 0x0F) |  +	  (scmds.continuousTone == SEC_TONE_ON ? 1 : 0) | +	  (scmds.voltage==SEC_VOLTAGE_18 ? 2 : 0); + +	if (ioctl(fd_sec, SEC_SEND_SEQUENCE, &scmds) < 0) +		perror("setfront sec"); + +	while(tune_it(&frp)); + + +/* +	if ((fd_demuxa=open("/dev/ost/demux", O_RDWR|O_NONBLOCK))  +	    < 0){ +		perror("DEMUX DEVICE: "); +		return -1; +	} +        memset(&sctFilterParams.filter, 0, sizeof(struct dmx_filter)); +        sctFilterParams.pid                       = 0x1fff; +        sctFilterParams.filter.filter[0]          = 0x00; +        sctFilterParams.filter.mask[0]            = 0x00; +        sctFilterParams.timeout                   = 0; +        sctFilterParams.flags                     = DMX_IMMEDIATE_START; + +        if (ioctl(fd_demuxa, DMX_SET_FILTER, &sctFilterParams) < 0)   +                perror("DMX SET FILTER:"); + + +	get_sect(fd_demuxa); +*/ +	pesFilterParamsA.pid = 0x1fff; +	pesFilterParamsA.input = DMX_IN_FRONTEND;  +	pesFilterParamsA.output = DMX_OUT_TS_TAP;  +	pesFilterParamsA.pes_type = DMX_PES_OTHER;  +	pesFilterParamsA.flags = DMX_IMMEDIATE_START; +	if (ioctl(fd_demuxa, DMX_SET_PES_FILTER,  +		  &pesFilterParamsA) < 0) +		perror("set_apid"); + +	while(1); +} diff --git a/test/test_tt.c b/test/test_tt.c new file mode 100644 index 0000000..6511f39 --- /dev/null +++ b/test/test_tt.c @@ -0,0 +1,205 @@ +/* test_tt.c - example of using PES filter for teletext output. + *             c.f. ETSI EN-300-472 + * + * usage: DEMUX=/dev/dvb/adapterX/demuxX test_tt PID + * + * Copyright (C) 2002 convergence GmbH + * Johannes Stezenbach <js@convergence.de> based on code by + * Ralph Metzler <ralph@convergence.de> and Marcus Metzler <marcus@convergence.de> + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <errno.h> + +#include <linux/dvb/dmx.h> + +#include "hex_dump.h" + +#define MAX_PES_SIZE (4*1024) + + +uint8_t reverse[] = { +0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0, +0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8, +0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4, +0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC, +0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2, +0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA, +0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6, +0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE, +0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1, +0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9, +0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5, +0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD, +0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3, +0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB, +0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7, +0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF +}; + + + +void usage(void) +{ +	fprintf(stderr, "usage: test_tt PID\n"); +	fprintf(stderr, "       The default demux device used can be changed\n"); +	fprintf(stderr, "       using the DEMUX environment variable\n"); +	exit(1); +} + +void safe_read(int fd, void *buf, int count) +{ +	int bytes; + +	do { +		bytes = read(fd, buf, count); +		if (bytes < 0) { +			if (errno == EOVERFLOW) +				fprintf(stderr, "read error: buffer overflow (%d)\n", +						EOVERFLOW); +			else { +				perror("read"); +				exit(1); +			} +		} +		else if (bytes == 0) { +			fprintf(stderr, "got EOF on demux!?\n"); +			exit(1); +		} +	} while (bytes < count); +} + +void process_pes(int fd) +{ +	uint8_t buf[MAX_PES_SIZE]; +	int i, plen, hlen, sid, lines, l; + +	/* search for start of next PES data block 0x000001bd */ +	for (;;) { +		safe_read(fd, buf, 1); +		if (buf[0] != 0) continue; +		safe_read(fd, buf, 1); +		if (buf[0] != 0) continue; +		safe_read(fd, buf, 1); +		if (buf[0] != 1) continue; +		safe_read(fd, buf, 1); +		if (buf[0] == 0xbd) +			break; +	} + +	safe_read(fd, buf, 5); +	/* PES packet length */ +	plen = ((buf[0] << 8) | buf[1]) & 0xffff; + +	/* PES header data length */ +	hlen = buf[4]; +	if (hlen != 0x24) { +		fprintf(stderr, "error: PES header data length != 0x24 (0x%02x)\n", hlen); +		return; +	} +	/* skip rest of PES header */ +	safe_read(fd, buf, hlen); + +	/* read stream ID */ +	safe_read(fd, buf, 1); +	sid = buf[0]; +	if (sid < 0x10 || sid > 0x1f) { +		fprintf(stderr, "error: non-EBU stream ID 0x%02x\n", sid); +		return; +	} + +	/* number of VBI lines */ +	lines = (plen + 6) / 46 - 1; + +	/* read VBI data */ +	for (l = 0; l < lines; l++) { +		safe_read(fd, buf, 46); +		if (buf[1] != 44) { +			fprintf(stderr, "error: VBI line has invalid length\n"); +			return; +		} +		/* bit twiddling */ +		for (i = 2; i < 46; i++) +			buf[i] = reverse[buf[i]]; +		/* framing code, should be 11100100b */ +		if (buf[3] != 0x27) { +			fprintf(stderr, "error: wrong framing code\n"); +			return; +		} +		/* remaining data needs to be hamming decoded, but we should +		 * be able to read some partial strings */ +		hex_dump(buf, 46); +		printf("\n"); +	} +} + +int set_filter(int fd, unsigned int pid) +{ +	struct dmx_pes_filter_params f; + +	f.pid = (uint16_t) pid; +	f.input = DMX_IN_FRONTEND; +	f.output = DMX_OUT_TAP; +	f.pes_type = DMX_PES_OTHER; /* DMX_PES_TELETEXT if you want vbi insertion */ +	f.flags = DMX_IMMEDIATE_START; +	if (ioctl(fd, DMX_SET_PES_FILTER, &f) == -1) { +		perror("ioctl DMX_SET_PES_FILTER"); +		return 1; +	} +	return 0; +} + + +int main(int argc, char *argv[]) +{ +	int dmxfd; +	unsigned long pid; +	char * dmxdev = "/dev/dvb/adapter0/demux0"; + +	if (argc != 2) +		usage(); + +	pid = strtoul(argv[1], NULL, 0); +	if (pid > 0x1fff) +		usage(); +	if (getenv("DEMUX")) +		dmxdev = getenv("DEMUX"); +	fprintf(stderr, "test_tt: using '%s'\n", dmxdev); +	fprintf(stderr, "         PID 0x%04lx\n", pid); + +	if ((dmxfd = open(dmxdev, O_RDWR)) < 0){ +		perror("open"); +		return 1; +	} + +	if (set_filter(dmxfd, pid) != 0) +		return 1; + +	for (;;) { +		process_pes(dmxfd); +	} + +	close(dmxfd); +	return 0; +} + diff --git a/test/test_vevent.c b/test/test_vevent.c new file mode 100644 index 0000000..f61143e --- /dev/null +++ b/test/test_vevent.c @@ -0,0 +1,125 @@ +/*  + * test_vevent.c - Test VIDEO_GET_EVENT and poll(9 for video events + * + * Copyright (C) 2003 convergence GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + */ + +#include <sys/ioctl.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/poll.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <linux/dvb/video.h> + + +int videoGetSize(int fd, char *arg) +{ +	video_size_t size; + +	if (arg) +		return -1; +	if (ioctl(fd, VIDEO_GET_SIZE, &size) == -1){ +		perror("VIDEO_GET_SIZE"); +		return 0; +	} + +	printf("Video Size: %ux%u ", size.w, size.h); +	switch (size.aspect_ratio) { +	case VIDEO_FORMAT_4_3: +		printf("4:3 (%d)\n", size.aspect_ratio); +		break; +	case VIDEO_FORMAT_16_9: +		printf("16:9 (%d)\n", size.aspect_ratio); +		break; +	case VIDEO_FORMAT_221_1: +		printf("2.21:1 (%d)\n", size.aspect_ratio); +		break; +	default: +		printf("unknown aspect ratio (%d)\n", size.aspect_ratio); +		break; +	} +	return 0; +} + +int main(void) +{ +	int vfd, rc; +	char *videodev = "/dev/dvb/adapter0/video0"; +	struct pollfd pfd[1]; +	struct video_event event; + +	if (getenv("VIDEO")) +		videodev = getenv("VIDEO"); + +	printf("using video device '%s'\n", videodev); + +	if((vfd = open(videodev, O_RDONLY | O_NONBLOCK)) < 0) { +		perror("open video device"); +		return 1; +	} + +	videoGetSize(vfd, NULL); + +	pfd[0].fd = vfd; +	pfd[0].events = POLLPRI; + +	for (;;) { +		rc = poll(pfd, 1, -1); +		if (rc == -1) { +			perror("poll"); +			return -1; +		} +		printf("poll events: %#x\n", pfd[0].revents); +		if (pfd[0].revents & POLLPRI) { +			rc = ioctl(vfd, VIDEO_GET_EVENT, &event); +			if (rc == -1) { +				perror("VIDEO_GET_EVENT"); +				return -1; +			} +			printf("video event %d\n", event.type); +			if (event.type == VIDEO_EVENT_SIZE_CHANGED) { +				printf("  VIDEO_EVENT_SIZE_CHANGED %ux%u ", +						event.u.size.w, event.u.size.h); +				switch (event.u.size.aspect_ratio) { +				case VIDEO_FORMAT_4_3: +					printf("4:3 (%d)\n", event.u.size.aspect_ratio); +					break; +				case VIDEO_FORMAT_16_9: +					printf("16:9 (%d)\n", event.u.size.aspect_ratio); +					break; +				case VIDEO_FORMAT_221_1: +					printf("2.21:1 (%d)\n", event.u.size.aspect_ratio); +					break; +				default: +					printf("unknown aspect ratio (%d)\n", +							event.u.size.aspect_ratio); +					break; +				} +			} +		} +	} + +	close(vfd); +	return 0; +} + diff --git a/test/test_video.c b/test/test_video.c new file mode 100644 index 0000000..09c2be1 --- /dev/null +++ b/test/test_video.c @@ -0,0 +1,368 @@ +/*  + * test_video.c - Test program for new API + * + * Copyright (C) 2000 Ralph  Metzler <ralph@convergence.de> + *                  & Marcus Metzler <marcus@convergence.de> +                      for convergence integrated media GmbH + * + * This program 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 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 Lesser General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. + * + */ + +#include <sys/ioctl.h> +#include <stdio.h> +#include <stdint.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <linux/dvb/dmx.h> +#include <linux/dvb/frontend_old.h> +#include <linux/dvb/sec.h> +#include <linux/dvb/video.h> +#include <sys/poll.h> + +int videoStop(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_STOP,0) < 0)){ +		perror("VIDEO STOP: "); +		return -1; +	} + +	return 0; +} + +int videoPlay(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_PLAY) < 0)){ +		perror("VIDEO PLAY: "); +		return -1; +	} + +	return 0; +} + + +int videoFreeze(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_FREEZE) < 0)){ +		perror("VIDEO FREEZE: "); +		return -1; +	} + +	return 0; +} + + +int videoContinue(int fd) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_CONTINUE) < 0)){ +		perror("VIDEO CONTINUE: "); +		return -1; +	} + +	return 0; +} + +int videoSelectSource(int fd, video_stream_source_t source) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_SELECT_SOURCE, source) < 0)){ +		perror("VIDEO SELECT SOURCE: "); +		return -1; +	} + +	return 0; +} + + + +int videoSetBlank(int fd, boolean state) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_SET_BLANK, state) < 0)){ +		perror("VIDEO SET BLANK: "); +		return -1; +	} + +	return 0; +} + +int videoFastForward(int fd,int nframes) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_FAST_FORWARD, nframes) < 0)){ +		perror("VIDEO FAST FORWARD: "); +		return -1; +	} + +	return 0; +} + +int videoSlowMotion(int fd,int nframes) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_SLOWMOTION, nframes) < 0)){ +		perror("VIDEO SLOWMOTION: "); +		return -1; +	} + +	return 0; +} + +int videoGetStatus(int fd) +{ +	struct video_status stat; +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_GET_STATUS, &stat) < 0)){ +		perror("VIDEO GET STATUS: "); +		return -1; +	} + +	printf("Video Status:\n"); +	printf("  Blank State          : %s\n", +	       (stat.video_blank ? "BLANK" : "STILL")); +	printf("  Play State           : "); +	switch ((int)stat.play_state){ +	case VIDEO_STOPPED: +		printf("STOPPED (%d)\n",stat.play_state); +		break; +	case VIDEO_PLAYING: +		printf("PLAYING (%d)\n",stat.play_state); +		break; +	case VIDEO_FREEZED: +		printf("FREEZED (%d)\n",stat.play_state); +		break; +	default: +		printf("unknown (%d)\n",stat.play_state); +		break; +	} +	 +	printf("  Stream Source        : "); +	switch((int)stat.stream_source){ +	case VIDEO_SOURCE_DEMUX: +		printf("DEMUX (%d)\n",stat.stream_source); +		break; +	case VIDEO_SOURCE_MEMORY: +		printf("MEMORY (%d)\n",stat.stream_source); +		break; +	default: +		printf("unknown (%d)\n",stat.stream_source); +		break; +	} + +	printf("  Format (Aspect Ratio): "); +	switch((int)stat.video_format){ +	case VIDEO_FORMAT_4_3: +		printf("4:3 (%d)\n",stat.video_format); +		break; +	case VIDEO_FORMAT_16_9: +		printf("16:9 (%d)\n",stat.video_format); +		break; +	default: +		printf("unknown (%d)\n",stat.video_format); +		break; +	} + +	printf("  Display Format       : "); +	switch((int)stat.display_format){ +	case VIDEO_PAN_SCAN: +		printf("Pan&Scan (%d)\n",stat.display_format); +		break; +	case VIDEO_LETTER_BOX: +		printf("Letterbox (%d)\n",stat.display_format); +		break; +	case VIDEO_CENTER_CUT_OUT: +		printf("Center cutout (%d)\n",stat.display_format); +		break; +	default: +		printf("unknown (%d)\n",stat.display_format); +		break; +	} +	return 0; +} + +int videoStillPicture(int fd, struct video_still_picture *sp) +{ +	int ans; + +	if ( (ans = ioctl(fd,VIDEO_STILLPICTURE, sp) < 0)){ +		perror("VIDEO STILLPICTURE: "); +		return -1; +	} + +	return 0; +} + +#define BUFFY 32768 +#define NFD   2 +void play_file_video(int filefd, int fd) +{ +	char buf[BUFFY]; +	int count; +	int written; +	struct pollfd pfd[NFD]; +	int stopped = 0; +	int ch; + +	pfd[0].fd = STDIN_FILENO; +	pfd[0].events = POLLIN; +	 +	pfd[1].fd = fd; +	pfd[1].events = POLLOUT; +	 +	videoSelectSource(fd,VIDEO_SOURCE_MEMORY); +	videoPlay(fd); +	 +	 +	count = read(filefd,buf,BUFFY); +	write(fd,buf,count); +	 +	while ( (count = read(filefd,buf,BUFFY)) >= 0  ){ +		written = 0; +		while(written < count){ +			if (poll(pfd,NFD,1)){ +				if (pfd[1].revents & POLLOUT){ +					written += write(fd,buf+written, +							count-written); +				} +				if (pfd[0].revents & POLLIN){ +					int c = getchar(); +					switch(c){ +					case 'z': +						videoFreeze(fd); +						printf("playback frozen\n"); +						stopped = 1; +						break; + +					case 's': +						videoStop(fd); +						printf("playback stopped\n"); +						stopped = 1; +						break; +						 +					case 'c': +						videoContinue(fd); +						printf("playback continued\n"); +						stopped = 0; +						break; + +					case 'p': +						videoPlay(fd); +						printf("playback started\n"); +						stopped = 0; +						break; + +					case 'f': +						videoFastForward(fd,0); +						printf("fastforward\n"); +						stopped = 0; +						break; + +					case 'm': +						videoSlowMotion(fd,2); +						printf("slowmotion\n"); +						stopped = 0; +						break; + +					case 'q': +						videoContinue(fd); +						exit(0); +						break; +					} +				} +				 +			} +		} +	} +} + +void load_iframe(int filefd, int fd) +{ +	struct stat st; +	struct video_still_picture sp; + +	fstat(filefd, &st); +	 +	sp.iFrame = (char *) malloc(st.st_size); +	sp.size = st.st_size; +	printf("I-frame size: %d\n", sp.size); +	 +	if(!sp.iFrame) { +		printf("No memory for I-Frame\n"); +		return; +	} + +	printf("read: %d bytes\n",read(filefd,sp.iFrame,sp.size)); +	videoStillPicture(fd,&sp); + +	sleep(3); +	videoPlay(fd); +} + +main(int argc, char **argv) +{ +	int fd; +	int filefd; + +	if (argc < 2) return -1; + +	if ( (filefd = open(argv[1],O_RDONLY)) < 0){ +		perror("File open:"); +		return -1; +	} +	if((fd = open("/dev/ost/video1",O_RDWR|O_NONBLOCK)) < 0){ +		perror("VIDEO DEVICE: "); +		return -1; +	} +	     +	 + + +//	videoSetBlank(fd,false); +	//videoPlay(fd); +	//sleep(4); +	//videoFreeze(fd); +	//sleep(3); +	//videoContinue(fd); +	//sleep(3); +	//videoStop(fd); +	videoGetStatus(fd); + + +	//load_iframe(filefd, fd); +	play_file_video(filefd, fd); +	close(fd); +	close(filefd); +	return 0; + + +} + diff --git a/test/video.c b/test/video.c new file mode 100644 index 0000000..ea9e4a2 --- /dev/null +++ b/test/video.c @@ -0,0 +1,182 @@ + /** + *  A tiny video watching application, just starts capturing /dev/video + *  into /dev/fb0. + *  Be shure to have >8Bit/pixel color resolution and r/w access for  + *  /dev/video0, /dev/fb0 and /dev/tty0 to let this work... + * + *   compile with + * + *   $ gcc -g -Wall -O2 -o video video.c -I../../ost/include + */ + +#include <sys/mman.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/time.h> +#include <unistd.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <linux/fb.h> +#include <linux/videodev.h> + +#define VIDEO_DEV "/dev/video0" +#define FB_DEV "/dev/fb0" +#define VT_DEV "/dev/tty0" + +static char *video_devname = VIDEO_DEV; + +#define min(a,b)	(a) < (b) ? (a) : (b) + +static int zero = 0; +static int one = 1; + +static struct fb_var_screeninfo fb_var; +static struct fb_fix_screeninfo fb_fix; + + +int init_fb (void) +{ +	const char blankoff_str[] = "\033[9;0]"; +	int fd, vt_fd; + +	fd = open (FB_DEV, O_RDWR); +	if (fd < 0) { +		perror("Could not open " FB_DEV ", please check permissions\n"); +		return 1; +	} + +	if ((vt_fd = open( VT_DEV, O_RDWR )) < 0) { +		perror("Could not open " VT_DEV ", please check permissions\n"); +		return 1; +	} + +	write( vt_fd, blankoff_str, strlen(blankoff_str) ); +	 +	if (ioctl (fd, FBIOGET_VSCREENINFO, &fb_var) < 0) { +		perror("Could not get variable screen information (fb_var)\n"); +		return 1; +	} + +	if (ioctl (fd, FBIOGET_FSCREENINFO, &fb_fix) < 0) { +		perror("Could not get fixed screen information (fb_fix)\n"); +		return 1; +	} + +	close (fd); +	return 0; +} + + +int init_video (int stop) +{ +	int fd; +	struct video_capability vcap; + +	if ((fd = open (video_devname, O_RDWR)) < 0) { +		fprintf (stderr,  +			 "%s: Could not open %s, please check permissions\n", +			 __FUNCTION__, video_devname); +		return -1; +	} + +	ioctl(fd, VIDIOCGCAP, &vcap); +	 +	if (ioctl(fd, VIDIOCCAPTURE, &zero) < 0) { +		perror("Could not stop capturing (VIDIOCCAPTURE failed)\n"); +		return -2; +	} + +	if (stop) +		return 0; +	 +	{ +		struct video_buffer b; +		b.base = (void*) fb_fix.smem_start; +		b.width = fb_var.xres; +		b.height = fb_var.yres; +		b.depth = fb_var.bits_per_pixel; +		b.bytesperline = fb_var.xres*((fb_var.bits_per_pixel+7)/8); +		if (ioctl(fd, VIDIOCSFBUF, &b) < 0) { +			fprintf(stderr, "VIDIOCSFBUF failed, must run as root?\n"); +			return -3; +		} +	} +	 +	{ +		struct video_picture p; +		if (ioctl(fd, VIDIOCGPICT, &p) < 0) { +			perror("VIDIOCGPICT failed\n"); +			return -4; +		} +		p.depth = fb_var.bits_per_pixel; +		switch (fb_var.bits_per_pixel) { +			case 16: +				p.palette = VIDEO_PALETTE_RGB565; +				break; +			case 24: +				p.palette = VIDEO_PALETTE_RGB24; +				break; +			case 32: +				p.palette = VIDEO_PALETTE_RGB32; +				break; +		} +		//p.contrast = 0x8000; +		//p.colour = 0x6000; +		if (ioctl(fd, VIDIOCSPICT, &p) < 0) { +			perror("VIDIOCSPICT failed\n"); +			return -5; +		} +	} +	 +	{ +		struct video_window win; +		win.width = min((__u32) vcap.maxwidth, fb_var.xres); +		win.height = min((__u32) vcap.maxheight, fb_var.yres); +		win.x = 0; +		win.y = 0; +		win.flags = 0; +		win.clips = NULL; +		win.clipcount = 0; +		win.chromakey = 0; +		if (ioctl(fd, VIDIOCSWIN, &win) < 0) { +			perror("VIDIOCSWIN failed\n"); +			return -6; +		} +	} +	 +	if (ioctl(fd, VIDIOCCAPTURE, &one) < 0) { +		perror("Could not start capturing (VIDIOCCAPTURE failed)\n"); +		return -7; +	} +	 +	close (fd); +	 +	return 0; +} + +int main (int argc, char **argv) +{ +	int err = 0, stop = 0; + +	if ((err = init_fb())) +		return err; + +	if ((argc == 2 && strcmp(argv[1], "stop") == 0) || +	    (argc == 3 && strcmp(argv[2], "stop") == 0)) +		stop = 1; + +	if ((argc == 2 && !stop) || argc == 3) +		video_devname = argv[1]; + +	if (argc != 1 && argc != 2 && !(argc == 3 && stop)) { +		fprintf (stderr, "usage: %s <devname> <stop>\n", argv[0]); +		exit (-1); +	} + +	return init_video (stop); +} + diff --git a/util/Makefile b/util/Makefile new file mode 100644 index 0000000..6e6daa3 --- /dev/null +++ b/util/Makefile @@ -0,0 +1,12 @@ +# Makefile for linuxtv.org dvb-apps/util + +%:: FORCE +	$(MAKE) -C lib $(MAKECMDGOALS) +	$(MAKE) -C szap $(MAKECMDGOALS) +	$(MAKE) -C scan $(MAKECMDGOALS) +	$(MAKE) -C dvbnet $(MAKECMDGOALS) +	$(MAKE) -C dvbdate $(MAKECMDGOALS) +	$(MAKE) -C dvbtraffic $(MAKECMDGOALS) +	$(MAKE) -C av7110_loadkeys $(MAKECMDGOALS) + +FORCE: diff --git a/util/av7110_loadkeys/Makefile b/util/av7110_loadkeys/Makefile new file mode 100644 index 0000000..e83e069 --- /dev/null +++ b/util/av7110_loadkeys/Makefile @@ -0,0 +1,48 @@ +CC = gcc +CFLAGS = -g -Wall -O2 + +all: av7110_loadkeys evtest + +av7110_loadkeys: av7110_loadkeys.o + +evtest: evtest.o + +av7110_loadkeys.o: av7110_loadkeys.c input_keynames.h + +evtest.o: evtest.c input_keynames.h + + +input_keynames.h: /usr/include/linux/input.h input_fake.h +	@echo 'generate $@...' +	@echo '#ifndef __INPUT_KEYNAMES_H__' > $@ +	@echo '#define __INPUT_KEYNAMES_H__' >> $@ +	@echo '' >> $@ +	@echo '#include <linux/input.h>' >> $@ +	@echo '' >> $@ +	@echo '#if !defined(KEY_OK)' >> $@ +	@echo '#include "input_fake.h"' >> $@ +	@echo '#endif' >> $@ +	@echo '' >> $@ +	@echo '' >> $@ +	@echo 'struct input_key_name {' >> $@ +	@echo '        const char *name;' >> $@ +	@echo '        int         key;' >> $@ +	@echo '};' >> $@ +	@echo '' >> $@ +	@echo '' >> $@ +	@echo 'static struct input_key_name key_name [] = {' >> $@ +	@for x in `cat /usr/include/linux/input.h input_fake.h | \ +	          grep KEY_ | grep "#define" | grep -v KEY_MAX | \ +		  cut -f 1 | cut -f 2 -d ' ' | sort | uniq` ; do \ +		echo "        { \"`echo $$x | cut -b 5-`\", $$x }," >> $@ \ +		; \ +	done +	@echo '};' >> $@ +	@echo '' >> $@ +	@echo '#endif  /* __INPUT_KEYNAMES_H */' >> $@ +	@echo '' >> $@ + + +clean: +	$(RM) core* *.o input_keynames.h av7110_loadkeys evtest + diff --git a/util/av7110_loadkeys/README b/util/av7110_loadkeys/README new file mode 100644 index 0000000..b778e9a --- /dev/null +++ b/util/av7110_loadkeys/README @@ -0,0 +1,64 @@ +Hi, + +this is a utility to setup IR control keymaps using the /proc/av7110_ir  +interface. + +just call  + +   # ./av7110_loadkeys [-i|--invert] [-a|--address <num>] keymapname.(rc5|rcmm) > /proc/av7110_ir + +If your IR receiver hardware inverts the signal, you should use the -i  +or --invert command line option. + +If you have two or more devices which use the same IR protocol, you should +specify the -a or --address parameter. If the parameter is omitted, the +driver listens to all device addresses. Some examples: + +Listen to *any* IR transmitter with uses the RC5 protocol: +# ./av7110_loadkeys hauppauge.rc5 > /proc/av7110_ir + +Listen to RC5 transmitter with address 2: +# ./av7110_loadkeys -a 2 hauppauge.rc5 > /proc/av7110_ir + +If you don't know the correct value for the -a parameter, take a look +on the debug output of the driver (see below). + +Now you can test your hardware setup using evtest + +   # ./evtest /dev/input/eventX + +where eventX is the IR input event device, usually event0 if you don't +use USB mice or keyboards. + +------------------------------------------------------------------------ + +Keymaps are in format: + +   <key> <associated input keycode> + +   0x00   KEY_0 +   0x01   KEY_1 +   0x42   KEY_HOME + +------------------------------------------------------------------------ + +In order to write a new keymap you might want to see the raw key  +values in the kernel log. Use + +   # insmod dvb-ttpci.o av7110_ir_debug=1 + +in order to enable some verbosity in the av7110_ir driver. Then watch +the kernel log while pressing your remote control keys. When you don't see +any messages in your kernel log you should check all electrical connections, +the selected protocol (RC5 or RCMM?) and the inversion setting. + +You find a list of all linux input key identifiers in </usr/include/input.h>  +and "./input_fake.h". + +Please post new keymaps on the linux-dvb mailing list or send them to  +me <holger@convergence.de>. + +have fun!  + +Holger + diff --git a/util/av7110_loadkeys/activy.rcmm b/util/av7110_loadkeys/activy.rcmm new file mode 100644 index 0000000..372df8e --- /dev/null +++ b/util/av7110_loadkeys/activy.rcmm @@ -0,0 +1,54 @@ +0x00 KEY_0 +0x01 KEY_1 +0x02 KEY_2 +0x03 KEY_3 +0x04 KEY_4 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_7 +0x08 KEY_8 +0x09 KEY_9 + +0x0c KEY_POWER +0x0a KEY_BACK + +0xfe KEY_SCROLLUP +0xff KEY_SCROLLDOWN + +0x40 KEY_GOTO +0x86 KEY_KEYBOARD + +0x87 KEY_RED +0xda KEY_GREEN +0xf3 KEY_YELLOW +0x88 KEY_BLUE + +0x82 KEY_HOME +0x54 KEY_MENU + +0x58 KEY_UP +0x59 KEY_DOWN +0x5a KEY_LEFT +0x5b KEY_RIGHT + +0x5c KEY_OK + +0xf0 KEY_CHANNELUP +0xef KEY_CHANNELDOWN + +0x10 KEY_VOLUMEUP +0x11 KEY_VOLUMEDOWN + +0x81 KEY_INFO +0x0d KEY_MUTE + +0x2f KEY_REWIND +0x2c KEY_PLAYPAUSE +0x2e KEY_FASTFORWARD +0x37 KEY_RECORD + +0x21 KEY_PREVIOUS +0x31 KEY_STOP +0x20 KEY_NEXT +0x42 KEY_EJECTCD + diff --git a/util/av7110_loadkeys/av7110_loadkeys.c b/util/av7110_loadkeys/av7110_loadkeys.c new file mode 100644 index 0000000..e9eeea0 --- /dev/null +++ b/util/av7110_loadkeys/av7110_loadkeys.c @@ -0,0 +1,186 @@ +#include <asm/types.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/mman.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <ctype.h> +#include <string.h> + +#include "input_keynames.h" + + +static +void print_error (const char *action, const char *file) +__attribute__ ((noreturn)); + + +static +void print_error (const char *action, const char *file) +{ +	static const char msg [] = "\nERROR: could not "; + +	write (0, msg, strlen(msg)); +	write (0, action, strlen(action)); +	write (0, " '", 2); +	write (0, file, strlen(file)); +	write (0, "'\n\n", 3); +	exit (-1); +} + + +static +int parse_keyname (char *pos, char **nend, int limit) +{ +	int cmp, index; +	int l = 1; +	int r = sizeof (key_name) / sizeof (key_name[0]); + +	if (limit < 5) +		return -1; + +	while ((*pos == ' ' || *pos == '\t') && limit > 0) { +		(*nend)++; +		pos++; +		limit--; +	} + +	if (pos [0] != 'K' || pos[1] != 'E' || pos[2] != 'Y' || pos[3] != '_') +		return -2; + +	(*nend) += 4; +	pos += 4; +	limit -= 4; + +	while (r >= l) { +		int len0, len1 = 0; + +		index = (l + r) / 2; +		 +		len0 = strlen(key_name[index-1].name); + +		while (len1 < limit && isgraph(pos[len1])) +			len1++; + +		cmp = strncmp (key_name[index-1].name, pos, +			       strlen(key_name[index-1].name)); +	 +		if (len0 < len1 && cmp == 0) +			cmp = -1; + +		if (cmp == 0) { +			*nend = pos + strlen (key_name[index-1].name); + +			if (**nend != '\n' && +			    **nend != '\t' && +			    **nend != ' ' && +			    *nend != pos) +				return -3; + +			return key_name[index-1].key; +		} + +		if (cmp < 0) +			l = index + 1; +		else +			r = index - 1; + +		if (r < l) { +			static const char msg [] = "\nunknown key '"; +			write (0, msg, strlen(msg)); +			write (0, pos-4, len1 + 4); +			write (0, "'\n", 2); +		} +	}; + +	return -4; +} + + + +const char usage [] = "\n\tusage: av7110_loadkeys [-i|--invert] [-a|--address <num>] keymap_filename.(rc5|rcmm)\n\n"; + + +struct ir_setup { +	__u32 ir_config; +	__u16 keytab [256]; +} __attribute__ ((packed)); + + +int main (int argc, char **argv) +{ +	static struct ir_setup setup; +	int i, fd; +	size_t len; +	char *buf, *pos, *fname = NULL; + +	for (i=1; i<argc; i++) { +		if (!strcmp("-i", argv[i]) || !strcmp("--invert", argv[i])) +			setup.ir_config |= 0x8000; +		else if (!strcmp("-a", argv[i]) || !strcmp("--address", argv[i])) { +			if (++i < argc) { +				setup.ir_config |= (atoi(argv[i]) & 0xff) << 16; +				setup.ir_config |= 0x4000; +			} +		} else +			fname = argv[i]; +	} + +	if (!fname) { +		write (0, usage, strlen(usage)); +		exit (-1); +	} + +	if (strncmp(".rcmm", fname + strlen(fname) - 5, 5) == 0) +		setup.ir_config |= 0x0001; +	else if (strncmp(".rc5", fname + strlen(fname) - 4, 4) != 0) { +		const char msg [] = "\nERROR: " +			"input filename must have suffix .rc5 or .rcmm\n"; +		write (0, msg, strlen(msg)); +		exit (-1); +	} + +	if ((fd = open (fname, O_RDONLY)) < 0) +		print_error ("open", fname); + +	len = lseek (fd, 0, SEEK_END); + +	if (!(pos = buf = mmap (NULL, len, PROT_READ, MAP_PRIVATE, fd, 0))) +		print_error ("mmap", fname); + +	while (pos < buf + len) { +		int key, keycode; +		 +		while (!isxdigit(*pos) && pos < buf + len) +			pos++; + +		if (pos == buf + len) +			break; +		 +		key = strtol (pos, &pos, 0); +		keycode = parse_keyname (pos, &pos, buf + len - pos); + +		if (key < 0 || key > 0xff) { +			const char msg [] =  +				"\nERROR: key must be in range 0 ... 0xff!\n\n"; + +			write (0, msg, strlen(msg)); +			exit (-1); +		} + +		if (keycode < 0) +			print_error ("parse", fname); + +		setup.keytab[key] = keycode; +	} +	 +	munmap (buf, len); +	close (fd); + +	write (1, &setup, 4 + 256 * sizeof(__u16)); + +	return 0; +} + + diff --git a/util/av7110_loadkeys/evtest.c b/util/av7110_loadkeys/evtest.c new file mode 100644 index 0000000..6714128 --- /dev/null +++ b/util/av7110_loadkeys/evtest.c @@ -0,0 +1,177 @@ +/* + * $Id: evtest.c,v 1.1 2004/01/17 16:59:46 js Exp $ + * + *  Copyright (c) 1999-2000 Vojtech Pavlik + * + *  Event device test program + */ + +/* + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + *  + * Should you need to contact me, the author, you can do so either by + * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: + * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic + */ + +#include <linux/input.h> + +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <stdlib.h> + +char *events[EV_MAX + 1] = { "Reset", "Key", "Relative", "Absolute", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +NULL, NULL, NULL, "LED", "Sound", NULL, "Repeat", "ForceFeedback", NULL, "ForceFeedbackStatus"}; +char *keys[KEY_MAX + 1] = { "Reserved", "Esc", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "Minus", "Equal", "Backspace", +"Tab", "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "LeftBrace", "RightBrace", "Enter", "LeftControl", "A", "S", "D", "F", "G", +"H", "J", "K", "L", "Semicolon", "Apostrophe", "Grave", "LeftShift", "BackSlash", "Z", "X", "C", "V", "B", "N", "M", "Comma", "Dot", +"Slash", "RightShift", "KPAsterisk", "LeftAlt", "Space", "CapsLock", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10", +"NumLock", "ScrollLock", "KP7", "KP8", "KP9", "KPMinus", "KP4", "KP5", "KP6", "KPPlus", "KP1", "KP2", "KP3", "KP0", "KPDot", "103rd", +"F13", "102nd", "F11", "F12", "F14", "F15", "F16", "F17", "F18", "F19", "F20", "KPEnter", "RightCtrl", "KPSlash", "SysRq", +"RightAlt", "LineFeed", "Home", "Up", "PageUp", "Left", "Right", "End", "Down", "PageDown", "Insert", "Delete", "Macro", "Mute", +"VolumeDown", "VolumeUp", "Power", "KPEqual", "KPPlusMinus", "Pause", "F21", "F22", "F23", "F24", "KPComma", "LeftMeta", "RightMeta", +"Compose", "Stop", "Again", "Props", "Undo", "Front", "Copy", "Open", "Paste", "Find", "Cut", "Help", "Menu", "Calc", "Setup", +"Sleep", "WakeUp", "File", "SendFile", "DeleteFile", "X-fer", "Prog1", "Prog2", "WWW", "MSDOS", "Coffee", "Direction", +"CycleWindows", "Mail", "Bookmarks", "Computer", "Back", "Forward", "CloseCD", "EjectCD", "EjectCloseCD", "NextSong", "PlayPause", +"PreviousSong", "StopCD", "Record", "Rewind", "Phone", "ISOKey", "Config", "HomePage", "Refresh", "Exit", "Move", "Edit", "ScrollUp", +"ScrollDown", "KPLeftParenthesis", "KPRightParenthesis", +"International1", "International2", "International3", "International4", "International5", +"International6", "International7", "International8", "International9", +"Language1", "Language2", "Language3", "Language4", "Language5", "Language6", "Language7", "Language8", "Language9", +NULL,  +"PlayCD", "PauseCD", "Prog3", "Prog4", "Suspend", "Close", +NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +"Btn0", "Btn1", "Btn2", "Btn3", "Btn4", "Btn5", "Btn6", "Btn7", "Btn8", "Btn9", +NULL, NULL,  NULL, NULL, NULL, NULL, +"LeftBtn", "RightBtn", "MiddleBtn", "SideBtn", "ExtraBtn", "ForwardBtn", "BackBtn", +NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +"Trigger", "ThumbBtn", "ThumbBtn2", "TopBtn", "TopBtn2", "PinkieBtn", +"BaseBtn", "BaseBtn2", "BaseBtn3", "BaseBtn4", "BaseBtn5", "BaseBtn6", +NULL, NULL, NULL, "BtnDead", +"BtnA", "BtnB", "BtnC", "BtnX", "BtnY", "BtnZ", "BtnTL", "BtnTR", "BtnTL2", "BtnTR2", "BtnSelect", "BtnStart", "BtnMode", +"BtnThumbL", "BtnThumbR", NULL, +"ToolPen", "ToolRubber", "ToolBrush", "ToolPencil", "ToolAirbrush", "ToolFinger", "ToolMouse", "ToolLens", NULL, NULL, +"Touch", "Stylus", "Stylus2", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  +"Ok", "Select", "Goto", "Clear", "Power2", "Option", "Info", "Time", "Vendor", +"Archive", "Program", "Channel", "Favorites", "EPG", "PVR", "MHP", "Language", +"Title", "Subtitle", "Angle", "Zoom", "Mode", "Keyboard", "Screen", "PC", "TV", +"TV2", "VCR", "VCR2", "Sat", "Sat2", "CD", "Tape", "Radio", "Tuner", "Player",  +"Text", "DVD", "Aux", "MP3", "Audio", "Video", "Directory", "List", "Memo", +"Calendar", "Red", "Green", "Yellow", "Blue", "ChannelUp", "ChannelDown",  +"First", "Last", "AB", "Play", "Restart", "Slow", "Shuffle", "FastForward",  +"Previous", "Next", "Digits", "Teen", "Twen", "Break" }; + +char *absval[5] = { "Value", "Min  ", "Max  ", "Fuzz ", "Flat " }; +char *relatives[REL_MAX + 1] = { "X", "Y", "Z", NULL, NULL, NULL, "HWheel", "Dial", "Wheel" }; +char *absolutes[ABS_MAX + 1] = { "X", "Y", "Z", "Rx", "Ry", "Rz", "Throttle", "Rudder", "Wheel", "Gas", "Brake", +NULL, NULL, NULL, NULL, NULL, +"Hat0X", "Hat0Y", "Hat1X", "Hat1Y", "Hat2X", "Hat2Y", "Hat3X", "Hat 3Y", "Pressure", "Distance", "XTilt", "YTilt"}; +char *leds[LED_MAX + 1] = { "NumLock", "CapsLock", "ScrollLock", "Compose", "Kana", "Sleep", "Suspend", "Mute" }; +char *repeats[REP_MAX + 1] = { "Delay", "Period" }; +char *sounds[SND_MAX + 1] = { "Bell", "Click" }; + +char **names[EV_MAX + 1] = { events, keys, relatives, absolutes, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +NULL, NULL, leds, sounds, NULL, repeats, NULL, NULL, NULL }; + +#define BITS_PER_LONG (sizeof(long) * 8) +#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) +#define OFF(x)  ((x)%BITS_PER_LONG) +#define BIT(x)  (1UL<<OFF(x)) +#define LONG(x) ((x)/BITS_PER_LONG) +#define test_bit(bit, array)	((array[LONG(bit)] >> OFF(bit)) & 1) + +int main (int argc, char **argv) +{ +	int fd, rd, i, j, k; +	struct input_event ev[64]; +	int version; +	unsigned short id[4]; +	unsigned long bit[EV_MAX][NBITS(KEY_MAX)]; +	char name[256] = "Unknown"; +	int abs[5]; + +	if (argc < 2) { +		printf("Usage: evtest /dev/input/eventX\n"); +		printf("Where X = input device number\n"); +		exit(1); +	} + +	if ((fd = open(argv[argc - 1], O_RDONLY)) < 0) { +		perror("evtest"); +		exit(1); +	} + +	if (ioctl(fd, EVIOCGVERSION, &version)) { +		perror("evtest: can't get version"); +		exit(1); +	} + +	printf("Input driver version is %d.%d.%d\n", +		version >> 16, (version >> 8) & 0xff, version & 0xff); + +	ioctl(fd, EVIOCGID, id); +	printf("Input device ID: bus 0x%x vendor 0x%x product 0x%x version 0x%x\n", +		id[ID_BUS], id[ID_VENDOR], id[ID_PRODUCT], id[ID_VERSION]); + +	ioctl(fd, EVIOCGNAME(sizeof(name)), name); +	printf("Input device name: \"%s\"\n", name); + +	memset(bit, 0, sizeof(bit)); +	ioctl(fd, EVIOCGBIT(0, EV_MAX), bit[0]); +	printf("Supported events:\n"); + +	for (i = 0; i < EV_MAX; i++) +		if (test_bit(i, bit[0])) { +			printf("  Event type %d (%s)\n", i, events[i] ? events[i] : "?"); +			ioctl(fd, EVIOCGBIT(i, KEY_MAX), bit[i]); +			for (j = 0; j < KEY_MAX; j++)  +				if (test_bit(j, bit[i])) { +					printf("    Event code %d (%s)\n", j, names[i] ? (names[i][j] ? names[i][j] : "?") : "?"); +					if (i == EV_ABS) { +						ioctl(fd, EVIOCGABS(j), abs); +						for (k = 0; k < 5; k++) +							if ((k < 3) || abs[k]) +								printf("      %s %6d\n", absval[k], abs[k]); +					} +				} +		} +		 + +	printf("Testing ... (interrupt to exit)\n"); + +	while (1) { +		rd = read(fd, ev, sizeof(struct input_event) * 64); + +		if (rd < (int) sizeof(struct input_event)) { +			printf("yyy\n"); +			perror("\nevtest: error reading"); +			exit (1); +		} + +		for (i = 0; i < rd / sizeof(struct input_event); i++) +			printf("Event: time %ld.%06ld, type %d (%s), code %d (%s), value %d\n", +				ev[i].time.tv_sec, ev[i].time.tv_usec, ev[i].type, +				events[ev[i].type] ? events[ev[i].type] : "?", +				ev[i].code, +				names[ev[i].type] ? (names[ev[i].type][ev[i].code] ? names[ev[i].type][ev[i].code] : "?") : "?", +				ev[i].value); + +	} +} + diff --git a/util/av7110_loadkeys/galaxis.rcmm b/util/av7110_loadkeys/galaxis.rcmm new file mode 100644 index 0000000..86268e9 --- /dev/null +++ b/util/av7110_loadkeys/galaxis.rcmm @@ -0,0 +1,51 @@ +0x00 KEY_0 +0x01 KEY_1 +0x02 KEY_2 +0x03 KEY_3 +0x04 KEY_4 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_7 +0x08 KEY_8 +0x09 KEY_9 + +0x0a KEY_MHP +0x0c KEY_POWER +0x0d KEY_MUTE +0x0f KEY_INFO +0x10 KEY_VOLUMEUP +0x11 KEY_VOLUMEDOWN +0x20 KEY_CHANNELUP +0x21 KEY_CHANNELDOWN +0x3c KEY_TEXT +0x3f KEY_TV + +0x45 KEY_SETUP +0x4b KEY_SUBTITLE +0x4e KEY_LANGUAGE + +0x50 KEY_RADIO +0x55 KEY_EXIT + +0x58 KEY_UP +0x59 KEY_DOWN +0x5a KEY_LEFT +0x5b KEY_RIGHT +0x5c KEY_OK + +0x6d KEY_RED +0x6e KEY_GREEN +0x6f KEY_YELLOW +0x70 KEY_BLUE +	 +0x78 KEY_MENU +0x79 KEY_LIST +0xcc KEY_EPG + +0xc4 KEY_UP +0xc5 KEY_UP +0xc6 KEY_DOWN +0xc7 KEY_DOWN + +0xff KEY_VCR + diff --git a/util/av7110_loadkeys/hauppauge.rc5 b/util/av7110_loadkeys/hauppauge.rc5 new file mode 100644 index 0000000..c9a65b3 --- /dev/null +++ b/util/av7110_loadkeys/hauppauge.rc5 @@ -0,0 +1,25 @@ +0x00 KEY_0 +0x01 KEY_1 +0x02 KEY_2 +0x03 KEY_3 +0x04 KEY_4 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_7 +0x08 KEY_8 +0x09 KEY_9 + +0x0c KEY_RADIO +0x0d KEY_MUTE +0x0f KEY_TV + +0x10 KEY_VOLUMEUP +0x11 KEY_VOLUMEDOWN +0x1e KEY_VENDOR + +0x20 KEY_CHANNELUP +0x21 KEY_CHANNELDOWN +0x22 KEY_SELECT +0x26 KEY_CYCLEWINDOWS +0x2e KEY_SCREEN + diff --git a/util/av7110_loadkeys/hauppauge_grey.rc5 b/util/av7110_loadkeys/hauppauge_grey.rc5 new file mode 100644 index 0000000..ac186dc --- /dev/null +++ b/util/av7110_loadkeys/hauppauge_grey.rc5 @@ -0,0 +1,40 @@ + +0x3d KEY_POWER +0x3b KEY_GOTO + +0x00 KEY_0 +0x01 KEY_1 +0x02 KEY_2 +0x03 KEY_3 +0x04 KEY_4 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_7 +0x08 KEY_8 +0x09 KEY_9 + +0x1f KEY_EXIT +0x0d KEY_MENU + +0x0b KEY_RED +0x2e KEY_GREEN +0x38 KEY_YELLOW +0x29 KEY_BLUE + +0x11 KEY_LEFT +0x10 KEY_RIGHT +0x20 KEY_UP +0x21 KEY_DOWN +0x25 KEY_OK + +0x0f KEY_MUTE +0x0c KEY_INFO +0x3c KEY_EPG +0x32 KEY_REWIND +0x35 KEY_PLAY +0x34 KEY_FASTFORWARD +0x37 KEY_RECORD +0x36 KEY_STOP +0x30 KEY_PAUSE +0x24 KEY_PREVIOUS +0x1e KEY_NEXT diff --git a/util/av7110_loadkeys/input_fake.h b/util/av7110_loadkeys/input_fake.h new file mode 100644 index 0000000..7aecc9f --- /dev/null +++ b/util/av7110_loadkeys/input_fake.h @@ -0,0 +1,84 @@ +#ifndef _INPUT_FAKE_H +#define _INPUT_FAKE_H + +#include <linux/input.h> + + +#if !defined(KEY_OK) + +/** + *  define some additional remote control keys in case they  + *  were not already defined above in <linux/input.h> + */ + +#define KEY_OK           0x160 +#define KEY_SELECT       0x161 +#define KEY_GOTO         0x162 +#define KEY_CLEAR        0x163 +#define KEY_POWER2       0x164 +#define KEY_OPTION       0x165 +#define KEY_INFO         0x166 +#define KEY_TIME         0x167 +#define KEY_VENDOR       0x168 +#define KEY_ARCHIVE      0x169 +#define KEY_PROGRAM      0x16a +#define KEY_CHANNEL      0x16b +#define KEY_FAVORITES    0x16c +#define KEY_EPG          0x16d +#define KEY_PVR          0x16e +#define KEY_MHP          0x16f +#define KEY_LANGUAGE     0x170 +#define KEY_TITLE        0x171 +#define KEY_SUBTITLE     0x172 +#define KEY_ANGLE        0x173 +#define KEY_ZOOM         0x174 +#define KEY_MODE         0x175 +#define KEY_KEYBOARD     0x176 +#define KEY_SCREEN       0x177 +#define KEY_PC           0x178 +#define KEY_TV           0x179 +#define KEY_TV2          0x17a +#define KEY_VCR          0x17b +#define KEY_VCR2         0x17c +#define KEY_SAT          0x17d +#define KEY_SAT2         0x17e +#define KEY_CD           0x17f +#define KEY_TAPE         0x180 +#define KEY_RADIO        0x181 +#define KEY_TUNER        0x182 +#define KEY_PLAYER       0x183 +#define KEY_TEXT         0x184 +#define KEY_DVD          0x185 +#define KEY_AUX          0x186 +#define KEY_MP3          0x187 +#define KEY_AUDIO        0x188 +#define KEY_VIDEO        0x189 +#define KEY_DIRECTORY    0x18a +#define KEY_LIST         0x18b +#define KEY_MEMO         0x18c +#define KEY_CALENDAR     0x18d +#define KEY_RED          0x18e +#define KEY_GREEN        0x18f +#define KEY_YELLOW       0x190 +#define KEY_BLUE         0x191 +#define KEY_CHANNELUP    0x192 +#define KEY_CHANNELDOWN  0x193 +#define KEY_FIRST        0x194 +#define KEY_LAST         0x195 +#define KEY_AB           0x196 +#define KEY_PLAY         0x197 +#define KEY_RESTART      0x198 +#define KEY_SLOW         0x199 +#define KEY_SHUFFLE      0x19a +#define KEY_FASTFORWARD  0x19b +#define KEY_PREVIOUS     0x19c +#define KEY_NEXT         0x19d +#define KEY_DIGITS       0x19e +#define KEY_TEEN         0x19f +#define KEY_TWEN         0x1a0 +#define KEY_BREAK        0x1a1 + + +#endif  /* !defined(KEY_OK)  */ +#endif  /* _INPUT_FAKE_H */ + diff --git a/util/av7110_loadkeys/mbo_81095-code_562.rc5 b/util/av7110_loadkeys/mbo_81095-code_562.rc5 new file mode 100644 index 0000000..357e410 --- /dev/null +++ b/util/av7110_loadkeys/mbo_81095-code_562.rc5 @@ -0,0 +1,39 @@ +0x0c KEY_POWER + +0x01 KEY_1 +0x02 KEY_2 +0x03 KEY_3 +0x04 KEY_4 + +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_7 +0x08 KEY_8 + +0x09 KEY_9 +0x00 KEY_0 +0x0a KEY_F11 +0x2b KEY_F12 + +0x3f KEY_PROGRAM +0x23 KEY_CONFIG +0x0d KEY_MUTE + +0x11 KEY_VOLUMEDOWN +0x10 KEY_VOLUMEUP +0x20 KEY_CHANNELUP +0x21 KEY_CHANNELDOWN +0x29 KEY_TV + +0x1a KEY_RED +0x1b KEY_GREEN +0x2e KEY_YELLOW +0x24 KEY_BLUE + +0x32 KEY_REWIND +0x35 KEY_PLAY +0x34 KEY_FORWARD +0x37 KEY_RECORD + +0x36 KEY_STOP +0x30 KEY_PAUSE diff --git a/util/av7110_loadkeys/medion_088.rc5 b/util/av7110_loadkeys/medion_088.rc5 new file mode 100644 index 0000000..ebec3fe --- /dev/null +++ b/util/av7110_loadkeys/medion_088.rc5 @@ -0,0 +1,36 @@ +0x00 KEY_0 +0x01 KEY_1 +0x02 KEY_2 +0x03 KEY_3 +0x04 KEY_4 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_7 +0x08 KEY_8 +0x09 KEY_9 + +0x0b KEY_BACK +0x0c KEY_POWER +0x0d KEY_MUTE +0x0e KEY_MENU +0x0f KEY_TV + +0x10 KEY_VOLUMEUP +0x11 KEY_VOLUMEDOWN +0x12 KEY_UP +0x13 KEY_DOWN +0x14 KEY_RIGHT +0x15 KEY_LEFT +0x1e KEY_VENDOR + +0x20 KEY_CHANNELUP +0x21 KEY_CHANNELDOWN +0x22 KEY_SELECT +0x23 KEY_OK +0x26 KEY_CYCLEWINDOWS +0x2e KEY_SCREEN + +0x37 KEY_RED +0x36 KEY_GREEN +0x34 KEY_BLUE +0x32 KEY_YELLOW diff --git a/util/av7110_loadkeys/medion_155.rc5 b/util/av7110_loadkeys/medion_155.rc5 new file mode 100644 index 0000000..416bbd9 --- /dev/null +++ b/util/av7110_loadkeys/medion_155.rc5 @@ -0,0 +1,35 @@ +0x00 KEY_0 +0x01 KEY_1 +0x02 KEY_2 +0x03 KEY_3 +0x04 KEY_4 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_7 +0x08 KEY_8 +0x09 KEY_9 + +0x35 KEY_BACK +0x0c KEY_POWER +0x0d KEY_MUTE +0x3f KEY_MENU +0x0f KEY_TV + +0x10 KEY_VOLUMEUP +0x11 KEY_VOLUMEDOWN +0x12 KEY_UP +0x13 KEY_DOWN +0x14 KEY_RIGHT +0x15 KEY_LEFT + +0x0a KEY_CHANNELUP +0x0b KEY_CHANNELDOWN +0x22 KEY_SELECT +0x23 KEY_OK +0x26 KEY_CYCLEWINDOWS +0x2e KEY_SCREEN + +0x37 KEY_RED +0x36 KEY_GREEN +0x34 KEY_BLUE +0x32 KEY_YELLOW diff --git a/util/av7110_loadkeys/philips.rc5 b/util/av7110_loadkeys/philips.rc5 new file mode 100644 index 0000000..68bc85d --- /dev/null +++ b/util/av7110_loadkeys/philips.rc5 @@ -0,0 +1,32 @@ +0x00 KEY_0 +0x01 KEY_1 +0x02 KEY_2 +0x03 KEY_3 +0x04 KEY_4 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_7 +0x08 KEY_8 +0x09 KEY_9 + +0x0b KEY_MENU +0x0c KEY_POWER +0x0d KEY_MUTE +0x0e KEY_OK +0x0f KEY_MINUS +0x10 KEY_VOLUMEUP +0x11 KEY_VOLUMEDOWN + +0x20 KEY_CHANNELUP +0x21 KEY_CHANNELDOWN +0x26 KEY_INFO +0x2d KEY_ZOOM +0x2e KEY_CYCLEWINDOWS + +0x32 KEY_PLAY +0x34 KEY_FORWARD +0x36 KEY_STOP +0x37 KEY_REWIND +0x38 KEY_AUX +0x3c KEY_TEXT +0x3f KEY_SCREEN diff --git a/util/av7110_loadkeys/philips1358.rc5 b/util/av7110_loadkeys/philips1358.rc5 new file mode 100644 index 0000000..e30efba --- /dev/null +++ b/util/av7110_loadkeys/philips1358.rc5 @@ -0,0 +1,37 @@ +0x00 KEY_0 +0x01 KEY_1 +0x02 KEY_2 +0x03 KEY_3 +0x04 KEY_4 +0x05 KEY_5 +0x06 KEY_6 +0x07 KEY_7 +0x08 KEY_8 +0x09 KEY_9 +0x0C KEY_POWER +0x0D KEY_MUTE +0x0E KEY_OK +0x0F KEY_DIGITS +0x10 KEY_RIGHT +0x11 KEY_LEFT +0x1E KEY_STOP +0x20 KEY_UP +0x21 KEY_DOWN +0x23 KEY_AB +0x24 KEY_RECORD +0x25 KEY_SUBTITLE +0x26 KEY_INFO +0x29 KEY_PLAY +0x2A KEY_FORWARD +0x2B KEY_PAUSE +0x2C KEY_REWIND +0x2D KEY_F4 +0x2E KEY_F3  +0x32 KEY_YELLOW +0x34 KEY_BLUE +0x36 KEY_GREEN +0x37 KEY_RED +0x38 KEY_AUX +0x3C KEY_F2  +0x3D KEY_SCREEN +0x3F KEY_F1 
\ No newline at end of file diff --git a/util/dvbdate/Makefile b/util/dvbdate/Makefile new file mode 100644 index 0000000..ea514db --- /dev/null +++ b/util/dvbdate/Makefile @@ -0,0 +1,25 @@ + +CC      = gcc +CFLAGS  = -g -O2 -MD -Wall -I. -I../../include +LFLAGS  = + +OBJS    = dvbdate.o +TARGET  = dvbdate +DESTDIR = /usr/local/bin/ + +all: $(TARGET) + +.c.o: +	$(CC) $(CFLAGS) -c $< -o $@ + +$(TARGET): $(OBJS) +	$(CC) -o $@ $(OBJS) $(LFLAGS) + +install: all +	install -m 755 $(TARGET) $(DESTDIR)  + +clean: +	rm -f $(TARGET) $(OBJS) core* *~ *.d + +-include $(wildcard *.d) dummy + diff --git a/util/dvbdate/dvbdate.c b/util/dvbdate/dvbdate.c new file mode 100644 index 0000000..9821012 --- /dev/null +++ b/util/dvbdate/dvbdate.c @@ -0,0 +1,346 @@ +/* + +   dvbdate - a program to set the system date and time from a TDT multiplex + +   Copyright (C) Laurence Culhane 2002 <dvbdate@holmes.demon.co.uk> + +   Mercilessly ripped off from dvbtune, Copyright (C) Dave Chapman 2001 + +   Revamped by Johannes Stezenbach <js@convergence.de> +   and Michael Hunold <hunold@convergence.de> +   +   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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +   Or, point your browser to http://www.gnu.org/copyleft/gpl.html + +   Copyright (C) Laurence Culhane 2002 <dvbdate@holmes.demon.co.uk> + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <sys/ioctl.h> +#include <sys/poll.h> +#include <errno.h> +#include <getopt.h> +#include <stdarg.h> + +#include <linux/dvb/dmx.h> + +#define bcdtoint(i) ((((i & 0xf0) >> 4) * 10) + (i & 0x0f)) + +/* How many seconds can the system clock be out before we get warned? */ +#define ALLOWABLE_DELTA 30*60 + +char *ProgName; +int do_print; +int do_set; +int do_force; +int do_quiet; +int timeout = 25; + +void errmsg(char *message, ...) +{ +	va_list ap; + +	va_start(ap, message); +	fprintf(stderr, "%s: ", ProgName); +	vfprintf(stderr, message, ap); +	va_end(ap); +} + +void usage() +{ +	fprintf(stderr, "usage: %s [-p] [-s] [-f] [-q] [-h]\n", ProgName); +	_exit(1); +} + +void help() +{ +	fprintf(stderr, "\nhelp:\n" "%s [-p] [-s] [-f] [-q] [-h] [-t n]\n" "  --print	(print current time, TDT time and delta)\n" "  --set	(set the system clock to TDT time)\n" "  --force	(force the setting of the clock)\n" "  --quiet	(be silent)\n" "  --help	(display this message)\n""  --timout n	(max seconds to wait, default: 25)\n", ProgName); +	_exit(1); +} + +int do_options(int arg_count, char **arg_strings) +{ +	static struct option Long_Options[] = { +		{"print", 0, 0, 'p'}, +		{"set", 0, 0, 's'}, +		{"force", 0, 0, 'f'}, +		{"quiet", 0, 0, 'q'}, +		{"help", 0, 0, 'h'}, +		{"timeout", 1, 0, 't'}, +		{0, 0, 0, 0} +	}; +	int c; +	int Option_Index = 0; + +	while (1) { +		c = getopt_long(arg_count, arg_strings, "psfqht:", Long_Options, &Option_Index); +		if (c == EOF) +			break; +		switch (c) { +		case 't': +			timeout = atoi(optarg); +			if (0 == timeout) { +				fprintf(stderr, "%s: invalid timeout value\n", ProgName); +				usage(); +			} +			break; +		case 'p': +			do_print = 1; +			break; +		case 's': +			do_set = 1; +			break; +		case 'f': +			do_force = 1; +			break; +		case 'q': +			do_quiet = 1; +			break; +		case 'h': +			help(); +			break; +		case '?': +			usage(); +			break; +		case 0: +/* + * Which long option has been selected?  We only need this extra switch + * to cope with the case of wanting to assign two long options the same + * short character code. + */ +			printf("long option index %d\n", Option_Index); +			switch (Option_Index) { +			case 0:	/* Print */ +			case 1:	/* Set */ +			case 2:	/* Force */ +			case 3:	/* Quiet */ +			case 4:	/* Help */ +			case 5:	/* timout */ +				break; +			default: +				fprintf(stderr, "%s: unknown long option %d\n", ProgName, Option_Index); +				usage(); +			} +			break; +/* + * End of Special Long-opt handling code + */ +		default: +			fprintf(stderr, "%s: unknown getopt error - returned code %02x\n", ProgName, c); +			_exit(1); +		} +	} +	return 0; +} + +/* + * return the TDT time in UNIX time_t format + */ + +time_t convert_date(char *dvb_buf) +{ +	int i; +	int year, month, day, hour, min, sec; +	long int mjd; +	struct tm dvb_time; + +	mjd = (dvb_buf[0] & 0xff) << 8; +	mjd += (dvb_buf[1] & 0xff); +	hour = bcdtoint(dvb_buf[2] & 0xff); +	min = bcdtoint(dvb_buf[3] & 0xff); +	sec = bcdtoint(dvb_buf[4] & 0xff); +/* + * Use the routine specified in ETSI EN 300 468 V1.4.1, + * "Specification for Service Information in Digital Video Broadcasting" + * to convert from Modified Julian Date to Year, Month, Day. + */ +	year = (int) ((mjd - 15078.2) / 365.25); +	month = (int) ((mjd - 14956.1 - (int) (year * 365.25)) / 30.6001); +	day = mjd - 14956 - (int) (year * 365.25) - (int) (month * 30.6001); +	if (month == 14 || month == 15) +		i = 1; +	else +		i = 0; +	year += i; +	month = month - 1 - i * 12; + +	dvb_time.tm_sec = sec; +	dvb_time.tm_min = min; +	dvb_time.tm_hour = hour; +	dvb_time.tm_mday = day; +	dvb_time.tm_mon = month - 1; +	dvb_time.tm_year = year; +	dvb_time.tm_isdst = -1; +	dvb_time.tm_wday = 0; +	dvb_time.tm_yday = 0; +	return (timegm(&dvb_time)); +} + + +/* + * Get the next UTC date packet from the TDT multiplex + */ + +int scan_date(time_t *dvb_time, unsigned int to) +{ +	int fd_date; +	int n, seclen; +	time_t t; +	unsigned char buf[4096]; +	struct dmx_sct_filter_params sctFilterParams; +	struct pollfd ufd; +	int found = 0; +	 +	t = 0; +	if ((fd_date = open("/dev/dvb/adapter0/demux0", O_RDWR | O_NONBLOCK)) < 0) { +		perror("fd_date DEVICE: "); +		return -1; +	} + +	memset(&sctFilterParams, 0, sizeof(sctFilterParams)); +	sctFilterParams.pid = 0x14; +	sctFilterParams.timeout = 0; +	sctFilterParams.flags = DMX_IMMEDIATE_START; +	sctFilterParams.filter.filter[0] = 0x70; +	sctFilterParams.filter.mask[0] = 0xff; + +	if (ioctl(fd_date, DMX_SET_FILTER, &sctFilterParams) < 0) { +		perror("DATE - DMX_SET_FILTER:"); +		close(fd_date); +		return -1; +	} + +	while (to > 0) { +		int res; + +		memset(&ufd,0,sizeof(ufd)); +		ufd.fd=fd_date; +		ufd.events=POLLIN; + +		res = poll(&ufd,1,1000); +		if (0 == res) { +			fprintf(stdout, "."); +			fflush(stdout); +			to--; +			continue; +  		} +		if (1 == res) { +			found = 1; +			break; +		} +		errmsg("error polling for data"); +		close(fd_date); +		return -1; +	} +	fprintf(stdout, "\n"); +	if (0 == found) { +		errmsg("timeout - try tuning to a multiplex?\n"); +		close(fd_date); +		return -1; +	} + +	if ((n = read(fd_date, buf, 4096)) >= 3) { +		seclen = ((buf[1] & 0x0f) << 8) | (buf[2] & 0xff); +		if (n == seclen + 3) { +			t = convert_date(&(buf[3])); +		} else { +			errmsg("Under-read bytes for DATE - wanted %d, got %d\n", seclen, n); +			return 0; +		} +	} else { +		errmsg("Nothing to read from fd_date - try tuning to a multiplex?\n"); +		return 0; +	} +	close(fd_date); +	*dvb_time = t; +	return 0; +} + + +/* + * Set the system time + */ +int set_time(time_t * new_time) +{ +	if (stime(new_time)) { +		perror("Unable to set time"); +		return -1; +	} +	return 0; +} + + +int main(int argc, char **argv) +{ +	time_t dvb_time; +	time_t real_time; +	time_t offset; +	int ret; + +	do_print = 0; +	do_force = 0; +	do_set = 0; +	do_quiet = 0; +	ProgName = argv[0]; + +/* + * Process command line arguments + */ +	do_options(argc, argv); +	if (do_quiet && do_print) { +		errmsg("quiet and print options are mutually exclusive.\n"); +		exit(1); +	} +/* + * Get the date from the currently tuned TDT multiplex + */ +	ret = scan_date(&dvb_time, timeout); +	if (ret != 0) { +		errmsg("Unable to get time from multiplex.\n"); +		exit(1); +	} +	time(&real_time); +	offset = dvb_time - real_time; +	if (do_print) { +		fprintf(stdout, "System time: %s", ctime(&real_time)); +		fprintf(stdout, "   TDT time: %s", ctime(&dvb_time)); +		fprintf(stdout, "     Offset: %ld seconds\n", offset); +	} else if (!do_quiet) { +		fprintf(stdout, "%s", ctime(&dvb_time)); +	} +	if (do_set) { +		if (labs(offset) > ALLOWABLE_DELTA) { +			if (do_force) { +				if (0 != set_time(&dvb_time)) { +					errmsg("setting the time failed\n"); +				} +			} else { +				errmsg("multiplex time differs by more than %d from system.\n", ALLOWABLE_DELTA); +				errmsg("use -f to force system clock to new time.\n"); +				exit(1); +			} +		} else { +			set_time(&dvb_time); +		} +	}			/* #end if (do_set) */ +	return (0); +} diff --git a/util/dvbnet/Makefile b/util/dvbnet/Makefile new file mode 100644 index 0000000..187dee2 --- /dev/null +++ b/util/dvbnet/Makefile @@ -0,0 +1,29 @@ + +CC      = gcc +CFLAGS  = -g -O2 -MD -Wall -I. -I../../include +LFLAGS  = + +OBJS    = dvbnet.o +TARGET  = dvbnet +DESTDIR = /usr/local/bin/ + +all: version.h $(TARGET) + +.c.o: +	$(CC) $(CFLAGS) -c $< -o $@ + +$(TARGET): $(OBJS) +	$(CC) -o $@ $(OBJS) $(LFLAGS) + +version.h: +	printf '#define VERSION_INFO "%s (Build %s)"\n' \ +		"`cat $@.in`" "`date +'%a %b %d %X %Y'`" > $@ + +install: all +	install -m 755 $(TARGET) $(DESTDIR)  + +clean: +	rm -f $(TARGET) $(OBJS) version.h core* *~ *.d + +-include $(wildcard *.d) dummy + diff --git a/util/dvbnet/dvbnet.c b/util/dvbnet/dvbnet.c new file mode 100644 index 0000000..573fa59 --- /dev/null +++ b/util/dvbnet/dvbnet.c @@ -0,0 +1,205 @@ +/*  + * dvbnet.c + * + * Copyright (C) 2003 TV Files S.p.A + *                    L.Y.Mesentsev <lymes@tiscalinet.it> + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Or, point your browser to http://www.gnu.org/copyleft/gpl.html + *  + */ + +#include <stdio.h> +#include <fcntl.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <errno.h> + +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/ioctl.h> + +#include <linux/dvb/net.h> +#include <version.h> + +#ifndef VERSION_INFO +#define VERSION_INFO "1.1.0" +#endif + +#define OK    0 +#define FAIL -1 +#define DVB_NET_DEVICE "/dev/dvb/adapter%d/net%d" +#define DVB_NET_DEVICES_MAX 10 +#define IFNAME_DVB "dvb" + + +enum Mode { +	UNKNOWN, +	LST_INTERFACE, +	ADD_INTERFACE, +	DEL_INTERFACE +} op_mode; + +static int adapter = 0; +static int netdev = 0; +static struct dvb_net_if net_data; + +static void hello(void); +static void usage(char *); +static void parse_args(int, char **); +static int queryInterface(int, int); + +static char dvb_net_device[40]; + +int main(int argc, char **argv) +{ +	int fd_net; + +	hello(); + +	parse_args(argc, argv); + +	sprintf(dvb_net_device, DVB_NET_DEVICE, adapter, netdev); + +	printf("Device: %s\n", dvb_net_device); + +	if ((fd_net = open(dvb_net_device, O_RDWR | O_NONBLOCK)) < 0) { +		fprintf(stderr, "Error: couldn't open device %s: %d %m\n", +			dvb_net_device, errno); +		return FAIL; +	} + +	switch (op_mode) { +	case DEL_INTERFACE: +		if (ioctl(fd_net, NET_REMOVE_IF, net_data.if_num)) +			fprintf(stderr, +				"Error: couldn't remove interface %d: %d %m.\n", +				net_data.if_num, errno); +		else +			printf("Status: device %d removed successfully.\n", +			       net_data.if_num); +		break; + +	case ADD_INTERFACE: +		if (ioctl(fd_net, NET_ADD_IF, &net_data)) +			fprintf(stderr, +				"Error: couldn't add interface for pid %d: %d %m.\n", +				net_data.pid, errno); +		else +			printf +			    ("Status: device dvb%d_%d for pid %d created successfully.\n", +			     adapter, net_data.if_num, net_data.pid); +		break; + +	case LST_INTERFACE: +		queryInterface(fd_net, 0); +		break; + +	default: +		usage(argv[0]); +		return FAIL; +	} + +	close(fd_net); +	return OK; +} + + +int queryInterface(int fd_net, int dev) +{ +	struct dvb_net_if data; +	int IF, nIFaces = 0, ret = FAIL; + +	printf("Query DVB network interfaces:\n"); +	printf("-----------------------------\n"); +	for (IF = 0; IF < DVB_NET_DEVICES_MAX; IF++) { +		data.if_num = IF; +		if (ioctl(fd_net, NET_GET_IF, &data)) +			continue; + +		if (dev == data.if_num) +			ret = OK; + +		printf("Found device %d: interface dvb%d_%d, " +		       "listening on PID %d\n", +		       IF, adapter, data.if_num, data.pid); + +		nIFaces++; +	} + +	printf("-----------------------------\n"); +	printf("Found %d interface(s).\n\n", nIFaces); +	return ret; +} + + +void parse_args(int argc, char **argv) +{ +	char c, *s; +	op_mode = UNKNOWN; +	while ((c = getopt(argc, argv, "a:n:p:d:lvh")) != EOF) { +		switch (c) { +		case 'a': +			adapter = strtol(optarg, NULL, 0); +			break; +		case 'n': +			netdev = strtol(optarg, NULL, 0); +			break; +		case 'p': +			net_data.pid = strtol(optarg, NULL, 0); +			op_mode = ADD_INTERFACE; +			break; +		case 'd': +			net_data.if_num = strtol(optarg, NULL, 0); +			op_mode = DEL_INTERFACE; +			break; +		case 'l': +			op_mode = LST_INTERFACE; +			break; +		case 'v': +			exit(OK); +		case 'h': +		default: +			s = strrchr(argv[0], '/') + 1; +			usage((s) ? s : argv[0]); +			exit(FAIL); +		} +	} +} + + +void usage(char *prog_name) +{ +	fprintf(stderr, "Usage: %s [options]\n", prog_name); +	fprintf(stderr, "Where options are:\n"); +	fprintf(stderr, "\t-a AD  : Adapter card AD (default 0)\n"); +	fprintf(stderr, "\t-n NET : Net demux NET (default 0)\n"); +	fprintf(stderr, "\t-p PID : Add interface listening on PID\n"); +	fprintf(stderr, "\t-d NUM : Remove interface dvbAD_NUM\n"); +	fprintf(stderr, +		"\t-l     : List currently available interfaces\n"); +	fprintf(stderr, "\t-v     : Print current version\n\n"); +} + + +void hello(void) +{ +	printf("\nDVB Network Interface Manager\n"); +	printf("Version %s\n", VERSION_INFO); +	printf("Copyright (C) 2003, TV Files S.p.A\n\n"); +} diff --git a/util/dvbnet/net_start.pl b/util/dvbnet/net_start.pl new file mode 100755 index 0000000..71e6367 --- /dev/null +++ b/util/dvbnet/net_start.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl + +$ADAPTER = 0; + +&dvbnet($ADAPTER, 0,  512, "192.168.11.1"); +&dvbnet($ADAPTER, 0, 2000, "192.168.21.1"); + + +# &dvbnet(adapter,netdev,pid,"ip_addr"); + +sub dvbnet +{ +  local ($ADAPTER, $NETDEV, $PID, $IP_ADDR) = @_; + +  $DEV_NAME = `./dvbnet -a $ADAPTER -n $NETDEV -p $PID | grep created`; +  chop($DEV_NAME); + +  $DEV_NAME =~ s/(.*)device //; +  $DEV_NAME =~ s/for (.*)//; + +  $X = `/sbin/ifconfig $DEV_NAME $IP_ADDR netmask 255.255.255.0`; + +  system("/sbin/ifconfig $DEV_NAME"); +} + diff --git a/util/dvbnet/net_start.sh b/util/dvbnet/net_start.sh new file mode 100755 index 0000000..b155989 --- /dev/null +++ b/util/dvbnet/net_start.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +PID=0x511 +DEV_NAME=dvb0_0 +IP_ADDR=10.1.1.1 + +./dvbnet -p $PID + +/sbin/ifconfig $DEV_NAME $IP_ADDR + +# +#  you can reconfigure the MAC adress like this: +# +#MAC_ADDR=00:01:02:03:04:05 +#/sbin/ifconfig $DEV_NAME hw ether $MAC_ADDR diff --git a/util/dvbnet/version.h.in b/util/dvbnet/version.h.in new file mode 100644 index 0000000..d0a6e20 --- /dev/null +++ b/util/dvbnet/version.h.in @@ -0,0 +1 @@ +1.1.0-TVF diff --git a/util/dvbtraffic/Makefile b/util/dvbtraffic/Makefile new file mode 100644 index 0000000..c29be40 --- /dev/null +++ b/util/dvbtraffic/Makefile @@ -0,0 +1,6 @@ + +dvbtraffic: dvbtraffic.c +	gcc -MD -g -O2 -Wall -I../../include $< -o $@ + +clean: +	rm -f *.o *.d dvbtraffic diff --git a/util/dvbtraffic/dvbtraffic.c b/util/dvbtraffic/dvbtraffic.c new file mode 100644 index 0000000..8add053 --- /dev/null +++ b/util/dvbtraffic/dvbtraffic.c @@ -0,0 +1,130 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <time.h> +#include <sys/poll.h> +#include <sys/time.h> +#include <string.h> + +#include <linux/dvb/dmx.h> +#include <linux/dvb/frontend.h> +#include <linux/dvb/video.h> + +#define BSIZE 188 + +int pidt[0x2001]; + +int main(int argc, char **argv) +{ +	int fd, ffd, packets = 0; +	struct timeval startt; +	struct dmx_pes_filter_params flt; +	char *search; +	unsigned char buffer[BSIZE]; + +	fd = open("/dev/dvb/adapter0/dvr0", O_RDONLY); + +	ioctl(fd, DMX_SET_BUFFER_SIZE, 1024 * 1024); + +	ffd = open("/dev/dvb/adapter0/demux0", O_RDWR); +	if (ffd < 0) { +		perror("/dev/dvb/adapter0/demux0"); +		return -fd; +	} + +	flt.pid = 0x2000; +	flt.input = DMX_IN_FRONTEND; +	flt.output = DMX_OUT_TS_TAP; +	flt.pes_type = DMX_PES_OTHER; +	flt.flags = 0; + +	if (ioctl(ffd, DMX_SET_PES_FILTER, &flt) < 0) { +		perror("DMX_SET_PES_FILTER"); +		return -1; +	} + +	if (ioctl(ffd, DMX_START, 0) < 0) { +		perror("DMX_SET_PES_FILTER"); +		return -1; +	} + +	gettimeofday(&startt, 0); + +	if (argc > 1) +		search = argv[1]; +	else +		search = 0; + +	while (1) { +		int pid, r, ok; +		if ((r = read(fd, buffer, 188)) <= 0) { +			perror("read"); +			break; +		} +		if (r != 188) { +			printf("only read %d\n", r); +			break; +		} +		if (buffer[0] != 0x47) { +			continue; +			printf("desync (%x)\n", buffer[0]); +			while (buffer[0] != 0x47) +				read(fd, buffer, 1); +			continue; +		} +		ok = 1; +		pid = ((((unsigned) buffer[1]) << 8) | +		       ((unsigned) buffer[2])) & 0x1FFF; + +		if (search) { +			int i, sl = strlen(search); +			ok = 0; +			if (pid != 0x1fff) { +				for (i = 0; i < (188 - sl); ++i) { +					if (!memcmp(buffer + i, search, sl)) +						ok = 1; +				} +			} +		} + +		if (ok) { +			pidt[pid]++; +			pidt[0x2000]++; +		} + +		packets++; + +		if (!(packets & 0xFF)) { +			struct timeval now; +			int diff; +			gettimeofday(&now, 0); +			diff = +			    (now.tv_sec - startt.tv_sec) * 1000 + +			    (now.tv_usec - startt.tv_usec) / 1000; +			if (diff > 1000) { +				int pid = 0; +				for (pid = 0; pid < 0x2001; pid++) { +					if (pidt[pid]) { +						printf("%04x %5d p/s %5d kb/s %5d kbit\n", +						     pid, +						     pidt[pid] * 1000 / diff, +						     pidt[pid] * 1000 / diff * 188 / 1024, +						     pidt[pid] * 8 * 1000 / diff * 188 / 1000); +					} +					pidt[pid] = 0; +				} +				printf("-PID--FREQ-----BANDWIDTH-BANDWIDTH-\n"); +				startt = now; +			} +		} +	} + +	close(ffd); +	close(fd); +	return 0; +} + diff --git a/util/lib/Makefile b/util/lib/Makefile new file mode 100644 index 0000000..5f55636 --- /dev/null +++ b/util/lib/Makefile @@ -0,0 +1,20 @@ + +CC = gcc +CFLAGS = -MD -g -Wall -O2 -I../../include -I. +LFLAGS = -g -Wall + +OBJS = lnb.o +SRCS = $(OBJS:.o=.c) + +TARGET = lnb.o + +$(TARGET): $(SRCS) + +.c.o: +	$(CC) $(CFLAGS) -c $< -o $@ + +clean: +	$(RM) *.o *.d $(TARGET) + +-include $(wildcard *.d) dummy + diff --git a/util/lib/lnb.c b/util/lib/lnb.c new file mode 100644 index 0000000..d082181 --- /dev/null +++ b/util/lib/lnb.c @@ -0,0 +1,101 @@ +#include <stdlib.h> +#include <string.h> +#include <ctype.h> +#include "lnb.h" + +static char *univ_desc[] = { +		"Europe", +		"10800 to 11800 MHz and 11600 to 12700 Mhz", +		"Dual LO, loband 9750, hiband 10600 MHz", +		(char *)NULL }; + +static char *dbs_desc[] = { +		"Expressvu, North America", +		"12200 to 12700 MHz", +		"Single LO, 11250 MHz",	 +		(char *)NULL }; + +static char *standard_desc[] = { +		"10945 to 11450 Mhz", +		"Single LO, 10000 Mhz", +		(char *)NULL }; + +static char *enhan_desc[] = { +		"Astra", +		"10700 to 11700 MHz", +		"Single LO, 9750 MHz", +		(char *)NULL }; + +static char *cband_desc[] = { +		"Big Dish", +		"3700 to 4200 MHz", +		"Single LO, 5150 Mhz", +		(char *)NULL }; + +static struct lnb_types_st lnbs[] = { +	{"UNIVERSAL",	univ_desc,		9750, 10600, 11700 }, + 	{"DBS",		dbs_desc, 		11250, 0, 0 }, +	{"STANDARD",	standard_desc,		10000, 0, 0 }, +	{"ENHANCED",	enhan_desc,		9750, 0, 0 }, +	{"C-BAND",	cband_desc,		5150, 0, 0 } +}; + +/* Enumerate through standard types of LNB's until NULL returned. + * Increment curno each time + */ + +struct lnb_types_st * +lnb_enum(int curno) +{ +	if (curno >= sizeof(lnbs) / sizeof(lnbs[0])) +		return (struct lnb_types_st *)NULL; +	return &lnbs[curno]; +} + +/* Decode an lnb type, for example given on a command line + * If alpha and standard type, e.g. "Universal" then match that + * otherwise low[,high[,switch]] + */ + +int +lnb_decode(char *str, struct lnb_types_st *lnbp) +{ +int i; +char *cp, *np; + +	memset(lnbp, 0, sizeof(*lnbp)); +	cp = str; +	while(*cp && isspace(*cp)) +		cp++; +	if (isalpha(*cp)) { +		for(i = 0; i < (sizeof(lnbs) / sizeof(lnbs[0])); i++) { +			if (!strcasecmp(lnbs[i].name, cp)) { +				*lnbp = lnbs[i]; +				return 1; +			} +		} +		return -1; +	} +	if (*cp == '\0' || !isdigit(*cp)) +		return -1; +	lnbp->low_val = strtoul(cp, &np, 0); +	if (lnbp->low_val == 0) +		return -1; +	cp = np; +	while(*cp && (isspace(*cp) || *cp == ',')) +		cp++; +	if (*cp == '\0') +		return 1; +	if (!isdigit(*cp)) +		return -1; +	lnbp->high_val = strtoul(cp, &np, 0); +	cp = np; +	while(*cp && (isspace(*cp) || *cp == ',')) +		cp++; +	if (*cp == '\0') +		return 1; +	if (!isdigit(*cp)) +		return -1; +	lnbp->switch_val = strtoul(cp, NULL, 0); +	return 1; +} diff --git a/util/lib/lnb.h b/util/lib/lnb.h new file mode 100644 index 0000000..f78b7a6 --- /dev/null +++ b/util/lib/lnb.h @@ -0,0 +1,24 @@ + +struct lnb_types_st { +	char	*name; +	char	**desc; +	unsigned long	low_val; +	unsigned long	high_val;	/* zero indicates no hiband */ +	unsigned long	switch_val;	/* zero indicates no hiband */ +}; + +/* Enumerate through standard types of LNB's until NULL returned. + * Increment curno each time + */ + +struct lnb_types_st * +lnb_enum(int curno); + +/* Decode an lnb type, for example given on a command line + * If alpha and standard type, e.g. "Universal" then match that + * otherwise low[,high[,switch]] + */ + +int +lnb_decode(char *str, struct lnb_types_st *lnbp); + diff --git a/util/scan/Makefile b/util/scan/Makefile new file mode 100644 index 0000000..a82d865 --- /dev/null +++ b/util/scan/Makefile @@ -0,0 +1,21 @@ + +CC = gcc +CFLAGS = -MD -g -Wall -O2 -I../../include -I../lib +LFLAGS = -g -Wall + +OBJS = diseqc.o dump-zap.o dump-vdr.o scan.o ../lib/lnb.o +SRCS = $(OBJS:.o=.c) + +TARGET = scan + +$(TARGET): $(OBJS) +	$(CC) $(LFLAGS) -o $(TARGET) $(OBJS) + +.c.o: +	$(CC) $(CFLAGS) -c $< -o $@ + +clean: +	$(RM) *.o *.d $(TARGET) + +-include $(wildcard *.d) dummy + diff --git a/util/scan/README b/util/scan/README new file mode 100644 index 0000000..a6c1767 --- /dev/null +++ b/util/scan/README @@ -0,0 +1,18 @@ +Hi, + +this is a little channel scan utility to generate szap/tzap/czap compatible  +channel lists. Scan does not do a frequency scan, however, so you must +manually provide the data for tuning to one or more start transponders. +A number of initial-tuning-data files are provided for various dvb-c, dvb-s +and dvb-t networks around the world. If you make a new one feel free to +submit it to the linux-dvb mailing list http://linuxtv.org/mailinglists.xml. + +Basic usage: ./scan dvb-s/Astra-19.2E | tee mychannels.conf + +If you want it to check a specific frequency, tune to that frequency  +(e.g. using szap/tzap/czap) and then use './scan -c'. + +For more scan options see ./scan -h. + +Good luck, +Holger + Johannes diff --git a/util/scan/diseqc.c b/util/scan/diseqc.c new file mode 100644 index 0000000..c763261 --- /dev/null +++ b/util/scan/diseqc.c @@ -0,0 +1,108 @@ +#include <linux/dvb/frontend.h> +#include <sys/ioctl.h> +#include <time.h> + +#include "scan.h" +#include "diseqc.h" + + +struct diseqc_cmd switch_cmds[] = { +	{ { { 0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf2, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf1, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf3, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf4, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf6, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf5, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf7, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf8, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfa, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xf9, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfb, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfc, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfe, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xfd, 0x00, 0x00 }, 4 }, 0 }, +	{ { { 0xe0, 0x10, 0x38, 0xff, 0x00, 0x00 }, 4 }, 0 } +}; + + +/*--------------------------------------------------------------------------*/ + +static inline +void msleep(uint32_t msec) +{ +	struct timespec req = { msec / 1000, 1000000 * (msec % 1000) }; + +	while (nanosleep(&req, &req)) +		; +} + +#define printf(x...) + + +int diseqc_send_msg (int fd, fe_sec_voltage_t v, struct diseqc_cmd **cmd, +		     fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b) +{ +	int err; + +	if ((err = ioctl(fd, FE_SET_TONE, SEC_TONE_OFF))) +		return err; + +	if ((err = ioctl(fd, FE_SET_VOLTAGE, v))) +		return err; + +	msleep(15); +	while (*cmd) { +		debug("DiSEqC: %02x %02x %02x %02x %02x %02x\n", +		    (*cmd)->cmd.msg[0], (*cmd)->cmd.msg[1], +		    (*cmd)->cmd.msg[2], (*cmd)->cmd.msg[3], +		    (*cmd)->cmd.msg[4], (*cmd)->cmd.msg[5]); + +		if ((err = ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &(*cmd)->cmd))) +			return err; + +		msleep((*cmd)->wait); +		cmd++; +	} + +	//debug(" %s ", v == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" : +	//    v == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "???"); + +	//debug(" %s ", b == SEC_MINI_A ? "SEC_MINI_A" : +	//    b == SEC_MINI_B ? "SEC_MINI_B" : "???"); + +	//debug(" %s\n", t == SEC_TONE_ON ? "SEC_TONE_ON" : +	//    t == SEC_TONE_OFF ? "SEC_TONE_OFF" : "???"); + +	msleep(15); + +	if ((err = ioctl(fd, FE_DISEQC_SEND_BURST, b))) +		return err; + +	msleep(15); + +	return ioctl(fd, FE_SET_TONE, t); +} + + +int setup_switch (int frontend_fd, int switch_pos, int voltage_18, int hiband) +{ +	struct diseqc_cmd *cmd[2] = { NULL, NULL }; +	int i = 4 * switch_pos + 2 * hiband + (voltage_18 ? 1 : 0); + +	verbose("DiSEqC: switch pos %i, %sV, %sband (index %d)\n", +	    switch_pos, voltage_18 ? "18" : "13", hiband ? "hi" : "lo", i); + +	if (i < 0 || i >= sizeof(switch_cmds)/sizeof(struct diseqc_cmd)) +		return -EINVAL; + +	cmd[0] = &switch_cmds[i]; + +	return diseqc_send_msg (frontend_fd, +				i % 2 ? SEC_VOLTAGE_18 : SEC_VOLTAGE_13, +				cmd, +				(i/2) % 2 ? SEC_TONE_ON : SEC_TONE_OFF, +				(i/4) % 2 ? SEC_MINI_B : SEC_MINI_A); +} + + diff --git a/util/scan/diseqc.h b/util/scan/diseqc.h new file mode 100644 index 0000000..d44d99b --- /dev/null +++ b/util/scan/diseqc.h @@ -0,0 +1,25 @@ +#ifndef __DISEQC_H__ +#define __DISEQC_H__ + +#include <stdint.h> +#include <linux/dvb/frontend.h> + + +struct diseqc_cmd { +	struct dvb_diseqc_master_cmd cmd; +	uint32_t wait; +}; + + +extern int diseqc_send_msg (int fd, fe_sec_voltage_t v, struct diseqc_cmd **cmd, +			    fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b); + + +/** + *   set up the switch to position/voltage/tone + */ +extern int setup_switch (int frontend_fd, int switch_pos, int voltage_18, int freq); + + +#endif + diff --git a/util/scan/dump-vdr.c b/util/scan/dump-vdr.c new file mode 100644 index 0000000..8f86654 --- /dev/null +++ b/util/scan/dump-vdr.c @@ -0,0 +1,161 @@ +#include <stdio.h> +#include "dump-vdr.h" +#include <linux/dvb/frontend.h> + + +static const char *inv_name [] = { +	"0", +	"1", +	"999" +}; + +static const char *fec_name [] = { +	"0", +	"12", +	"23", +	"34", +	"45", +	"56", +	"67", +	"78", +	"89", +	"999" +}; + +static const char *qam_name [] = { +	"0", +	"16", +	"32", +	"64", +	"128", +	"256", +	"999" +}; + + +static const char *bw_name [] = { +	"8", +	"7", +	"6", +	"999" +}; + + +static const char *mode_name [] = { +	"2", +	"8", +	"999" +}; + +static const char *guard_name [] = { +	"32", +	"16", +	"8", +	"4", +	"999" +}; + + +static const char *hierarchy_name [] = { +	"0", +	"1", +	"2", +	"4", +	"999" +}; + +static const char *west_east_flag_name [] = { +	"W", +	"E" +}; + +void vdr_dump_dvb_parameters (FILE *f, fe_type_t type, +		struct dvb_frontend_parameters *p, +		char polarity, int orbital_pos, int we_flag) +{ +	switch (type) { +	case FE_QPSK: +		fprintf (f, "%i:", p->frequency / 1000); +		fprintf (f, "%c:", polarity); +		fprintf (f, "S%i.%i%s:", orbital_pos/10, +			 orbital_pos % 10, west_east_flag_name[we_flag]); +		fprintf (f, "%i:", p->u.qpsk.symbol_rate / 1000); +		break; + +	case FE_QAM: +		fprintf (f, "%i:", p->frequency / 1000000); +		fprintf (f, "M%s:C:", qam_name[p->u.qam.modulation]); +		fprintf (f, "%i:", p->u.qam.symbol_rate / 1000); +		break; + +	case FE_OFDM: +		fprintf (f, "%i:", p->frequency / 1000); +		fprintf (f, "I%s", inv_name[p->inversion]); +		fprintf (f, "B%s", bw_name[p->u.ofdm.bandwidth]); +		fprintf (f, "C%s", fec_name[p->u.ofdm.code_rate_HP]); +		fprintf (f, "D%s", fec_name[p->u.ofdm.code_rate_LP]); +		fprintf (f, "M%s", qam_name[p->u.ofdm.constellation]); +		fprintf (f, "T%s", mode_name[p->u.ofdm.transmission_mode]); +		fprintf (f, "G%s", guard_name[p->u.ofdm.guard_interval]); +		fprintf (f, "Y%s", hierarchy_name[p->u.ofdm.hierarchy_information]); +		fprintf (f, ":T:27500:"); +		break; + +	default: +		; +	}; +} + +void vdr_dump_service_parameter_set (FILE *f, +				 const char *service_name, +				 const char *provider_name, +				 fe_type_t type, +				 struct dvb_frontend_parameters *p, +				 char polarity, +				 int video_pid, +				 int pcr_pid, +				 uint16_t *audio_pid, +                                 int audio_num, +				 int teletext_pid, +				 int scrambled, +				 int ac3_pid, +                                 int service_id, +				 int network_id, +				 int transport_stream_id, +				 int orbital_pos, +				 int we_flag, +				 int dump_provider, +				 int ca_select, +				 int vdr_version, +				 int dump_channum, +				 int channel_num) +{ +        int i; + +	if ((video_pid || audio_pid[0]) && ((ca_select > 0) || ((ca_select == 0) && (scrambled == 0)))) { +		if ((dump_channum == 1) && (channel_num > 0)) +			fprintf(f, ":@%i\n", channel_num); +		if (dump_provider == 1) +			fprintf (f, "%s - ", provider_name); +		fprintf (f, "%s:", service_name); +		vdr_dump_dvb_parameters (f, type, p, polarity, orbital_pos, we_flag); +		if ((pcr_pid != video_pid) && (video_pid > 0)) +			fprintf (f, "%i+%i:", video_pid, pcr_pid); +		else +			fprintf (f, "%i:", video_pid); +		fprintf (f, "%i", audio_pid[0]); +	        for (i = 1; i < audio_num; i++) +			fprintf (f, ",%i", audio_pid[i]); +		if (ac3_pid) +			fprintf (f, ";%i", ac3_pid); +		if (scrambled == 1) scrambled = ca_select; +		if (vdr_version == 2) { +			network_id = 0; +			transport_stream_id = 0; +		}  +		fprintf (f, ":%d:%d:%d:%d:%d:0", teletext_pid, scrambled, +				service_id, network_id, transport_stream_id); +		fprintf (f, "\n"); +	} +} + diff --git a/util/scan/dump-vdr.h b/util/scan/dump-vdr.h new file mode 100644 index 0000000..0602026 --- /dev/null +++ b/util/scan/dump-vdr.h @@ -0,0 +1,38 @@ +#ifndef __DUMP_VDR_H__ +#define __DUMP_VDR_H__ + +#include <stdint.h> +#include <linux/dvb/frontend.h> + +extern +void vdr_dump_dvb_parameters (FILE *f, fe_type_t type, +		struct dvb_frontend_parameters *p, +		char polarity, int orbital_pos, int we_flag); + +extern +void vdr_dump_service_parameter_set (FILE *f, +				 const char *service_name, +				 const char *provider_name, +				 fe_type_t type, +				 struct dvb_frontend_parameters *p, +				 char polarity, +				 int video_pid, +				 int pcr_pid, +				 uint16_t *audio_pid, +                                 int audio_num, +				 int teletext_pid, +				 int scrambled, +				 int ac3_pid, +                                 int service_id, +				 int network_id, +				 int transport_stream_id, +				 int orbital_pos, +				 int we_flag, +				 int dump_provider, +				 int ca_select, +				 int vdr_version, +				 int dump_channum, +				 int channel_num); + +#endif + diff --git a/util/scan/dump-zap.c b/util/scan/dump-zap.c new file mode 100644 index 0000000..fb46a2a --- /dev/null +++ b/util/scan/dump-zap.c @@ -0,0 +1,119 @@ +#include <stdio.h> +#include <linux/dvb/frontend.h> +#include "dump-zap.h" + +static const char *inv_name [] = { +	"INVERSION_OFF", +	"INVERSION_ON", +	"INVERSION_AUTO" +}; + +static const char *fec_name [] = { +	"FEC_NONE", +	"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" +}; + + +static const char *qam_name [] = { +	"QPSK", +	"QAM_16", +	"QAM_32", +	"QAM_64", +	"QAM_128", +	"QAM_256", +	"QAM_AUTO" +}; + + +static const char *bw_name [] = { +	"BANDWIDTH_8_MHZ", +	"BANDWIDTH_7_MHZ", +	"BANDWIDTH_6_MHZ", +	"BANDWIDTH_AUTO" +}; + + +static const char *mode_name [] = { +	"TRANSMISSION_MODE_2K", +	"TRANSMISSION_MODE_8K", +	"TRANSMISSION_MODE_AUTO" +}; + +static const char *guard_name [] = { +	"GUARD_INTERVAL_1_32", +	"GUARD_INTERVAL_1_16", +	"GUARD_INTERVAL_1_8", +	"GUARD_INTERVAL_1_4", +	"GUARD_INTERVAL_AUTO" +}; + + +static const char *hierarchy_name [] = { +	"HIERARCHY_NONE", +	"HIERARCHY_1", +	"HIERARCHY_2", +	"HIERARCHY_4", +	"HIERARCHY_AUTO" +}; + + +void zap_dump_dvb_parameters (FILE *f, fe_type_t type, struct dvb_frontend_parameters *p, char polarity, int sat_number) +{ +	switch (type) { +	case FE_QPSK: +		fprintf (f, "%i:", p->frequency / 1000);	/* channels.conf wants MHz */ +		fprintf (f, "%c:", polarity); +		fprintf (f, "%d:", sat_number); +		fprintf (f, "%i", p->u.qpsk.symbol_rate / 1000); /* channels.conf wants kBaud */ +		/*fprintf (f, "%s", fec_name[p->u.qpsk.fec_inner]);*/ +		break; + +	case FE_QAM: +		fprintf (f, "%i:", p->frequency); +		fprintf (f, "%s:", inv_name[p->inversion]); +		fprintf (f, "%i:", p->u.qpsk.symbol_rate); +		fprintf (f, "%s:", fec_name[p->u.qpsk.fec_inner]); +		fprintf (f, "%s", qam_name[p->u.qam.modulation]); +		break; + +	case FE_OFDM: +		fprintf (f, "%i:", p->frequency); +		fprintf (f, "%s:", inv_name[p->inversion]); +		fprintf (f, "%s:", bw_name[p->u.ofdm.bandwidth]); +		fprintf (f, "%s:", fec_name[p->u.ofdm.code_rate_HP]); +		fprintf (f, "%s:", fec_name[p->u.ofdm.code_rate_LP]); +		fprintf (f, "%s:", qam_name[p->u.ofdm.constellation]); +		fprintf (f, "%s:", mode_name[p->u.ofdm.transmission_mode]); +		fprintf (f, "%s:", guard_name[p->u.ofdm.guard_interval]); +		fprintf (f, "%s", hierarchy_name[p->u.ofdm.hierarchy_information]); +		break; + +	default: +		; +	}; +} + +void zap_dump_service_parameter_set (FILE *f,  +				 const char *service_name, +				 fe_type_t type, +				 struct dvb_frontend_parameters *p, +				 char polarity, +				 int sat_number, +				 uint16_t video_pid, +				 uint16_t *audio_pid, +				 uint16_t service_id) +{ +	fprintf (f, "%s:", service_name); +	zap_dump_dvb_parameters (f, type, p, polarity, sat_number); +	fprintf (f, ":%i:%i:%i", video_pid, audio_pid[0], service_id); +	fprintf (f, "\n"); +} + diff --git a/util/scan/dump-zap.h b/util/scan/dump-zap.h new file mode 100644 index 0000000..6763dc2 --- /dev/null +++ b/util/scan/dump-zap.h @@ -0,0 +1,20 @@ +#ifndef __DUMP_ZAP_H__ +#define __DUMP_ZAP_H__ + +#include <stdint.h> +#include <linux/dvb/frontend.h> + +extern void zap_dump_dvb_parameters (FILE *f, fe_type_t type, +		struct dvb_frontend_parameters *t, char polarity, int sat); + +extern void zap_dump_service_parameter_set (FILE *f, +				 const char *service_name, +				 fe_type_t type, +				 struct dvb_frontend_parameters *t, +				 char polarity, int sat, +				 uint16_t video_pid, +				 uint16_t *audio_pid, +				 uint16_t service_id); + +#endif + diff --git a/util/scan/dvb-c/at-Vienna b/util/scan/dvb-c/at-Vienna new file mode 100644 index 0000000..2c3d29c --- /dev/null +++ b/util/scan/dvb-c/at-Vienna @@ -0,0 +1,3 @@ +# Kabel Vienna +# freq sr fec mod +C 377750000 6900000 NONE QAM256 diff --git a/util/scan/dvb-c/ch-unknown b/util/scan/dvb-c/ch-unknown new file mode 100644 index 0000000..a9852d1 --- /dev/null +++ b/util/scan/dvb-c/ch-unknown @@ -0,0 +1,3 @@ +# Kabel Suisse +# freq sr fec mod +C 530000000 6900000 NONE QAM64 diff --git a/util/scan/dvb-c/de-Berlin b/util/scan/dvb-c/de-Berlin new file mode 100644 index 0000000..4a53b74 --- /dev/null +++ b/util/scan/dvb-c/de-Berlin @@ -0,0 +1,4 @@ +# Kabel Berlin +# freq sr fec mod +C 394000000 6900000 NONE QAM64 +C 113000000 6900000 NONE QAM64 diff --git a/util/scan/dvb-c/de-iesy b/util/scan/dvb-c/de-iesy new file mode 100644 index 0000000..a289951 --- /dev/null +++ b/util/scan/dvb-c/de-iesy @@ -0,0 +1,3 @@ +# Kabel iesy +# freq sr fec mod +C 410000000 6900000 NONE QAM64 diff --git a/util/scan/dvb-c/fi-3ktv b/util/scan/dvb-c/fi-3ktv new file mode 100644 index 0000000..55ccfd6 --- /dev/null +++ b/util/scan/dvb-c/fi-3ktv @@ -0,0 +1,3 @@ +# 3KTV +# freq sr fec mod +C 306000000 6875000 NONE QAM64 diff --git a/util/scan/dvb-c/fi-vaasa-oncable b/util/scan/dvb-c/fi-vaasa-oncable new file mode 100644 index 0000000..380ccf7 --- /dev/null +++ b/util/scan/dvb-c/fi-vaasa-oncable @@ -0,0 +1,13 @@ +# OnCable (Finland / Vaasa) +# freq sr fec mod +C 386000000 6875000 NONE QAM64 +C 394000000 6875000 NONE QAM64 +C 143000000 6875000 NONE QAM64 +C 434000000 6875000 NONE QAM64 +C 362000000 6875000 NONE QAM64 +C 418000000 6875000 NONE QAM64 +C 426000000 6875000 NONE QAM64 +C 314000000 6875000 NONE QAM64 +C 410000000 6875000 NONE QAM64 +C 442000000 6875000 NONE QAM64 +C 306000000 6875000 NONE QAM64 diff --git a/util/scan/dvb-s/Astra-19.2E b/util/scan/dvb-s/Astra-19.2E new file mode 100644 index 0000000..74e1b59 --- /dev/null +++ b/util/scan/dvb-s/Astra-19.2E @@ -0,0 +1,3 @@ +# Astra 19.2E SDT info service transponder +# freq pol sr fec +S 12551500 V 22000000 5/6 diff --git a/util/scan/dvb-s/Hispasat-30.0W b/util/scan/dvb-s/Hispasat-30.0W new file mode 100644 index 0000000..2c200b5 --- /dev/null +++ b/util/scan/dvb-s/Hispasat-30.0W @@ -0,0 +1,6 @@ +# Hispasat 30.0W +# freq pol sr fec +S 11539000 V 24500000 5/6 +S 11931000 H 27500000 3/4 +S 12015000 V 27500000 3/4 +S 12567000 H 19850000 3/4 diff --git a/util/scan/dvb-s/Hotbird-13.0E b/util/scan/dvb-s/Hotbird-13.0E new file mode 100644 index 0000000..f2168da --- /dev/null +++ b/util/scan/dvb-s/Hotbird-13.0E @@ -0,0 +1,3 @@ +# EUTELSAT SkyPlex, Hotbird 13E +# freq pol sr fec +S 12539000 H 27500000 3/4 diff --git a/util/scan/dvb-s/PAS-43.0W b/util/scan/dvb-s/PAS-43.0W new file mode 100644 index 0000000..fab84c5 --- /dev/null +++ b/util/scan/dvb-s/PAS-43.0W @@ -0,0 +1,6 @@ +# PAS 6/6B/3R at 43.0W +# freq pol sr fec +S 12578000 H 19850000 3/4 +S 12584000 V 27500000 3/4 +S 12606000 H  6616000 3/4 +S 12665000 H 19850000 7/8 diff --git a/util/scan/dvb-s/Sirius-5.0E b/util/scan/dvb-s/Sirius-5.0E new file mode 100644 index 0000000..ec4e4ea --- /dev/null +++ b/util/scan/dvb-s/Sirius-5.0E @@ -0,0 +1,5 @@ +# Sirius 5.0E +# freq pol sr fec +S 11823000 V 27500000 3/4 +S 11977000 V 27500000 3/4 +S 12054000 V 27500000 3/4 diff --git a/util/scan/dvb-s/Telecom2-8.0W b/util/scan/dvb-s/Telecom2-8.0W new file mode 100644 index 0000000..91678b4 --- /dev/null +++ b/util/scan/dvb-s/Telecom2-8.0W @@ -0,0 +1,4 @@ +# Telecom2 8.0W +# freq pol sr fec +S 11635000 H 6800000 5/6 +S 12687000 V 1879000 3/4 diff --git a/util/scan/dvb-s/Telstar12-15.0W b/util/scan/dvb-s/Telstar12-15.0W new file mode 100644 index 0000000..529b91f --- /dev/null +++ b/util/scan/dvb-s/Telstar12-15.0W @@ -0,0 +1,4 @@ +# Telstar 12 15.0W +# freq pol sr fec +S 12041000 H 3256000 2/3 +S 12520000 V 8700000 1/2 diff --git a/util/scan/dvb-s/Thor-1.0W b/util/scan/dvb-s/Thor-1.0W new file mode 100644 index 0000000..1f8f1d2 --- /dev/null +++ b/util/scan/dvb-s/Thor-1.0W @@ -0,0 +1,8 @@ +# Thor 1.0W +# freq pol sr fec +S 11247000 V 24500000 7/8 +S 11293000 H 24500000 7/8 +S 11325000 H 24500000 7/8 +S 12054000 H 28000000 7/8 +S 12169000 H 28000000 7/8 +S 12226000 V 28000000 7/8 diff --git a/util/scan/dvb-s/Turksat-42.0E b/util/scan/dvb-s/Turksat-42.0E new file mode 100644 index 0000000..1ac7fd8 --- /dev/null +++ b/util/scan/dvb-s/Turksat-42.0E @@ -0,0 +1,4 @@ +# Turksat 42.0E +# freq pol sr fec +S 11594000 H 4557000 5/6 +S 10978000 V 2344000 3/4 diff --git a/util/scan/dvb-t/au-Darwin b/util/scan/dvb-t/au-Darwin new file mode 100644 index 0000000..522bb1d --- /dev/null +++ b/util/scan/dvb-t/au-Darwin @@ -0,0 +1,5 @@ +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 543625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE +T 550500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE +T 536625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE +T 557625000 7MHz 2/3 NONE QAM64 8k 1/8 NONE diff --git a/util/scan/dvb-t/au-canberra b/util/scan/dvb-t/au-canberra new file mode 100644 index 0000000..5e71b07 --- /dev/null +++ b/util/scan/dvb-t/au-canberra @@ -0,0 +1,12 @@ +# Australia / Canberra / Woden +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +# ABC +T 205625000 7MHz 3/4 3/4 QAM64 8k 1/16 NONE +# Seven +T 177500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE +# Nine +T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE +# Ten +T 219500000 7MHz 3/4 1/2 QAM64 8k 1/16 NONE +# SBS +T 543500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE diff --git a/util/scan/dvb-t/au-sydney_north_shore b/util/scan/dvb-t/au-sydney_north_shore new file mode 100644 index 0000000..0bb6dd4 --- /dev/null +++ b/util/scan/dvb-t/au-sydney_north_shore @@ -0,0 +1,12 @@ +# Australia / Sydney / North Shore (aka Artarmon/Gore Hill) +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +# ABC +T 226500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE +# Seven +T 177500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE +# Nine +T 191625000 7MHz 3/4 NONE QAM64 8k 1/16 NONE +# Ten +T 219500000 7MHz 3/4 NONE QAM64 8k 1/16 NONE +# SBS +T 571500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE diff --git a/util/scan/dvb-t/au-unknown b/util/scan/dvb-t/au-unknown new file mode 100644 index 0000000..9f96d9e --- /dev/null +++ b/util/scan/dvb-t/au-unknown @@ -0,0 +1,3 @@ +# Australia ABC +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 226500000 7MHz 2/3 NONE QAM64 8k 1/8 NONE diff --git a/util/scan/dvb-t/de-Berlin b/util/scan/dvb-t/de-Berlin new file mode 100644 index 0000000..416bd11 --- /dev/null +++ b/util/scan/dvb-t/de-Berlin @@ -0,0 +1,5 @@ +# DVB-T Berlin +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 522000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE     # ard / rbb +T 570000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE     # zdf +T 658000000 8MHz 2/3 NONE QAM16 8k 1/8 NONE     # t-systems diff --git a/util/scan/dvb-t/es-Collserola b/util/scan/dvb-t/es-Collserola new file mode 100644 index 0000000..04ffe54 --- /dev/null +++ b/util/scan/dvb-t/es-Collserola @@ -0,0 +1,6 @@ +# DVB-T Collserola (Barcelona) +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 650000000 8MHz 2/3 2/3 QAM64 8k 1/32 NONE     # C43: tvc +T 794000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE     # C61: tve, t5, a3, c+ +T 834000000 8MHz 2/3 NONE QAM64 8k 1/4 NONE     # C66: veotv, nettv + diff --git a/util/scan/dvb-t/fi-Espoo b/util/scan/dvb-t/fi-Espoo new file mode 100644 index 0000000..dd0619b --- /dev/null +++ b/util/scan/dvb-t/fi-Espoo @@ -0,0 +1,3 @@ +# Espoo A-mux (Digita Finland) +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE diff --git a/util/scan/dvb-t/fi-Tampere b/util/scan/dvb-t/fi-Tampere new file mode 100644 index 0000000..7e59894 --- /dev/null +++ b/util/scan/dvb-t/fi-Tampere @@ -0,0 +1,6 @@ +# Tampere DVB-T (Digita Finland) +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 578000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE +T 490000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE +T 770000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE + diff --git a/util/scan/dvb-t/fi-Turku b/util/scan/dvb-t/fi-Turku new file mode 100644 index 0000000..5f2d9b4 --- /dev/null +++ b/util/scan/dvb-t/fi-Turku @@ -0,0 +1,3 @@ +# Turku A-mux (Digita Finland) +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 714000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE diff --git a/util/scan/dvb-t/nl-AlphenaandenRijn b/util/scan/dvb-t/nl-AlphenaandenRijn new file mode 100644 index 0000000..f95d3a4 --- /dev/null +++ b/util/scan/dvb-t/nl-AlphenaandenRijn @@ -0,0 +1,7 @@ +# Digitenne (Alphen aan den Rijn, The Netherlands) +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy         +T 474000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE +T 578000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE +T 722000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE +T 762000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE +T 818000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE diff --git a/util/scan/dvb-t/nl-Randstad b/util/scan/dvb-t/nl-Randstad new file mode 100644 index 0000000..da1a74d --- /dev/null +++ b/util/scan/dvb-t/nl-Randstad @@ -0,0 +1,7 @@ +# Digitenne (Randstad, The Netherlands) +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy         +T 474000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE +T 490000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE +T 578000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE +T 762000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE +T 818000000 8MHz 1/2 NONE QAM64 8k 1/4 NONE diff --git a/util/scan/dvb-t/se-Gavle b/util/scan/dvb-t/se-Gavle new file mode 100644 index 0000000..04fe333 --- /dev/null +++ b/util/scan/dvb-t/se-Gavle @@ -0,0 +1,6 @@ +# Gavle (Senda/Boxer Sweden) +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 674000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE +T 498000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE +T 562000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE +T 706000000 8MHz 2/3 NONE QAM64 8k 1/8 NONE diff --git a/util/scan/dvb-t/uk-BlackHill b/util/scan/dvb-t/uk-BlackHill new file mode 100644 index 0000000..17eae72 --- /dev/null +++ b/util/scan/dvb-t/uk-BlackHill @@ -0,0 +1,3 @@ +# uk BlackHill +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 634167000 8MHz 2/3 NONE QAM64 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-CrystalPalace b/util/scan/dvb-t/uk-CrystalPalace new file mode 100644 index 0000000..9586b25 --- /dev/null +++ b/util/scan/dvb-t/uk-CrystalPalace @@ -0,0 +1,3 @@ +# Crystal Palace +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 505833333 8MHz 3/4 NONE QAM16 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-Hannington b/util/scan/dvb-t/uk-Hannington new file mode 100644 index 0000000..0bbbfdd --- /dev/null +++ b/util/scan/dvb-t/uk-Hannington @@ -0,0 +1,3 @@ +# Hannington, North Hampshire +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 706000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-Oxford b/util/scan/dvb-t/uk-Oxford new file mode 100644 index 0000000..035603e --- /dev/null +++ b/util/scan/dvb-t/uk-Oxford @@ -0,0 +1,3 @@ +# Oxford +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 578000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-PontopPike b/util/scan/dvb-t/uk-PontopPike new file mode 100644 index 0000000..c24ba92 --- /dev/null +++ b/util/scan/dvb-t/uk-PontopPike @@ -0,0 +1,3 @@ +# Pontop Pike, UK +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 690000000 8MHz 1/2 NONE QAM16 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-Redruth b/util/scan/dvb-t/uk-Redruth new file mode 100644 index 0000000..84dcb9a --- /dev/null +++ b/util/scan/dvb-t/uk-Redruth @@ -0,0 +1,3 @@ +# Redruth, Cornwall +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 618000000 8MHz 3/4 NONE QAM16 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-Reigate b/util/scan/dvb-t/uk-Reigate new file mode 100644 index 0000000..add0d8b --- /dev/null +++ b/util/scan/dvb-t/uk-Reigate @@ -0,0 +1,3 @@ +# Reigate +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 554000000 8MHz 2/3 NONE QAM64 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-Rowridge b/util/scan/dvb-t/uk-Rowridge new file mode 100644 index 0000000..c0c72a0 --- /dev/null +++ b/util/scan/dvb-t/uk-Rowridge @@ -0,0 +1,3 @@ +# Rowridge, Isle of Wight +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 489833333 8MHz 3/4 NONE QAM16 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-SandyHeath b/util/scan/dvb-t/uk-SandyHeath new file mode 100644 index 0000000..05d0474 --- /dev/null +++ b/util/scan/dvb-t/uk-SandyHeath @@ -0,0 +1,3 @@ +# Sandy Heath +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 641833334 8MHz 2/3 NONE QAM64 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-Storeton b/util/scan/dvb-t/uk-Storeton new file mode 100644 index 0000000..5c93ee9 --- /dev/null +++ b/util/scan/dvb-t/uk-Storeton @@ -0,0 +1,3 @@ +# Storeton, Wirral +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 546167000 8MHz 3/4 NONE QAM16 2k 1/32 NONE diff --git a/util/scan/dvb-t/uk-WinterHill b/util/scan/dvb-t/uk-WinterHill new file mode 100644 index 0000000..b000623 --- /dev/null +++ b/util/scan/dvb-t/uk-WinterHill @@ -0,0 +1,3 @@ +# Winter Hill, North-West England +# T freq bw fec_hi fec_lo mod transmission-mode guard-interval hierarchy +T 754166670 8MHz 3/4 NONE QAM16 2k 1/32 NONE diff --git a/util/scan/list.h b/util/scan/list.h new file mode 100644 index 0000000..6032c22 --- /dev/null +++ b/util/scan/list.h @@ -0,0 +1,140 @@ +#ifndef _LIST_H +#define _LIST_H + + +/* + * Simple doubly linked list implementation. + * + * Some of the internal functions ("__xxx") are useful when + * manipulating whole lists rather than single entries, as + * sometimes we already know the next/prev entries and we can + * generate better code by using them directly rather than + * using the generic single-entry routines. + */ + +struct list_head { +	struct list_head *next, *prev; +}; + +#define LIST_HEAD_INIT(name) { &(name), &(name) } + +#define LIST_HEAD(name) \ +	struct list_head name = LIST_HEAD_INIT(name) + +#define INIT_LIST_HEAD(ptr) do { \ +	(ptr)->next = (ptr); (ptr)->prev = (ptr); \ +} while (0) + +/* + * Insert a new entry between two known consecutive entries.  + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline__ void __list_add(struct list_head * new, +	struct list_head * prev, +	struct list_head * next) +{ +	next->prev = new; +	new->next = next; +	new->prev = prev; +	prev->next = new; +} + +/** + * list_add - add a new entry + * @new: new entry to be added + * @head: list head to add it after + * + * Insert a new entry after the specified head. + * This is good for implementing stacks. + */ +static __inline__ void list_add(struct list_head *new, struct list_head *head) +{ +	__list_add(new, head, head->next); +} + +/** + * list_add_tail - add a new entry + * @new: new entry to be added + * @head: list head to add it before + * + * Insert a new entry before the specified head. + * This is useful for implementing queues. + */ +static __inline__ void list_add_tail(struct list_head *new, struct list_head *head) +{ +	__list_add(new, head->prev, head); +} + +/* + * Delete a list entry by making the prev/next entries + * point to each other. + * + * This is only for internal list manipulation where we know + * the prev/next entries already! + */ +static __inline__ void __list_del(struct list_head * prev, +				  struct list_head * next) +{ +	next->prev = prev; +	prev->next = next; +} + +/** + * list_del - deletes entry from list. + * @entry: the element to delete from the list. + * Note: list_empty on entry does not return true after this, the entry is in an undefined state. + */ +static __inline__ void list_del(struct list_head *entry) +{ +	__list_del(entry->prev, entry->next); +} + +/** + * list_del_init - deletes entry from list and reinitialize it. + * @entry: the element to delete from the list. + */ +static __inline__ void list_del_init(struct list_head *entry) +{ +	__list_del(entry->prev, entry->next); +	INIT_LIST_HEAD(entry);  +} + +/** + * list_empty - tests whether a list is empty + * @head: the list to test. + */ +static __inline__ int list_empty(struct list_head *head) +{ +	return head->next == head; +} + +/** + * list_entry - get the struct for this entry + * @ptr:	the &struct list_head pointer. + * @type:	the type of the struct this is embedded in. + * @member:	the name of the list_struct within the struct. + */ +#define list_entry(ptr, type, member) \ +	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member))) + +/** + * list_for_each	-	iterate over a list + * @pos:	the &struct list_head to use as a loop counter. + * @head:	the head for your list. + */ +#define list_for_each(pos, head) \ +	for (pos = (head)->next; pos != (head); pos = pos->next) +        	 +/** + * list_for_each_safe	-	iterate over a list safe against removal of list entry + * @pos:	the &struct list_head to use as a loop counter. + * @n:		another &struct list_head to use as temporary storage + * @head:	the head for your list. + */ +#define list_for_each_safe(pos, n, head) \ +	for (pos = (head)->next, n = pos->next; pos != (head); \ +		pos = n, n = pos->next) + +#endif diff --git a/util/scan/scan.c b/util/scan/scan.c new file mode 100644 index 0000000..30d77a5 --- /dev/null +++ b/util/scan/scan.c @@ -0,0 +1,1928 @@ +/** + *  Simple MPEG parser to achieve network/service information. + * + *  refered standards: + * + *    ETSI EN 300 468 + *    ETSI TR 101 211 + *    ETSI ETR 211 + *    ITU-T H.222.0 + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/poll.h> +#include <unistd.h> +#include <fcntl.h> +#include <time.h> +#include <errno.h> +#include <signal.h> +#include <assert.h> + +#include <linux/dvb/frontend.h> +#include <linux/dvb/dmx.h> + +#include "list.h" +#include "diseqc.h" +#include "dump-zap.h" +#include "dump-vdr.h" +#include "scan.h" +#include "lnb.h" + + +static char demux_devname[80]; + +static struct dvb_frontend_info fe_info = { +	.type = -1 +}; + +int verbosity = 2; + +static int long_timeout; +static int current_tp_only; +static int get_other_nits; +static int vdr_dump_provider; +static int vdr_dump_channum; +static int ca_select = 1; +static int serv_select = 7; +static int vdr_version = 2; +static struct lnb_types_st lnb_type; + +static enum fe_spectral_inversion spectral_inversion = INVERSION_AUTO; + +enum table_type { +	PAT, +	PMT, +	SDT, +	NIT +}; + +enum format { +        OUTPUT_ZAP, +        OUTPUT_VDR, +	OUTPUT_PIDS +}; +static enum format output_format = OUTPUT_ZAP; + + +enum polarisation { +	POLARISATION_HORIZONTAL     = 0x00, +	POLARISATION_VERTICAL       = 0x01, +	POLARISATION_CIRCULAR_LEFT  = 0x02, +	POLARISATION_CIRCULAR_RIGHT = 0x03 +}; + +enum running_mode { +	RM_NOT_RUNNING = 0x01, +	RM_STARTS_SOON = 0x02, +	RM_PAUSING     = 0x03, +	RM_RUNNING     = 0x04 +}; + +#define AUDIO_CHAN_MAX (32) +#define CA_SYSTEM_ID_MAX (16) + +struct service { +	struct list_head list; +	int transport_stream_id; +	int service_id; +	char *provider_name; +	char *service_name; +	uint16_t pmt_pid; +	uint16_t pcr_pid; +	uint16_t video_pid; +	uint16_t audio_pid[AUDIO_CHAN_MAX]; +	char audio_lang[AUDIO_CHAN_MAX][4]; +	int audio_num; +	uint16_t ca_id[CA_SYSTEM_ID_MAX]; +	int ca_num; +	uint16_t teletext_pid; +	uint16_t subtitling_pid; +	uint16_t ac3_pid; +	unsigned int type         : 8; +	unsigned int scrambled	  : 1; +	enum running_mode running; +	void *priv; +	int channel_num; +}; + +struct transponder { +	struct list_head list; +	struct list_head services; +	int network_id; +	int transport_stream_id; +	enum fe_type type; +	struct dvb_frontend_parameters param; +	enum polarisation polarisation;		/* only for DVB-S */ +	int orbital_pos;			/* only for DVB-S */ +	unsigned int we_flag		  : 1;	/* West/East Flag - only for DVB-S */ +	unsigned int scan_done		  : 1; +	unsigned int last_tuning_failed	  : 1; +	unsigned int other_frequency_flag : 1;	/* DVB-T */ +	int n_other_f; +	uint32_t *other_f;			/* DVB-T freqeuency-list descriptor */ +}; + + +struct section_buf { +	struct list_head list; +	const char *dmx_devname; +	unsigned int run_once  : 1; +	unsigned int segmented : 1;	/* segmented by table_id_ext */ +	int fd; +	int pid; +	int table_id; +	int table_id_ext; +	int section_version_number; +	uint8_t section_done[32]; +	int sectionfilter_done; +	unsigned char buf[1024]; +	time_t timeout; +	time_t start_time; +	time_t running_time; +	struct section_buf *next_seg;	/* this is used to handle +					 * segmented tables (like NIT-other) +					 */ +}; + +static LIST_HEAD(scanned_transponders); +static LIST_HEAD(new_transponders); +static struct transponder *current_tp; + + +static void dump_dvb_parameters (FILE *f, struct transponder *p); + +static void setup_filter (struct section_buf* s, const char *dmx_devname, +		          int pid, int tid, int run_once, int segmented, int timeout); +static void add_filter (struct section_buf *s); + + +/* According to the DVB standards, the combination of network_id and + * transport_stream_id should be unique, but in real life the satellite + * operators and broadcasters don't care enough to coordinate + * the numbering. Thus we identify TPs by frequency (scan handles only + * one satellite at a time). Further complication: Different NITs on + * one satellite sometimes list the same TP with slightly different + * frequencies, so we have to search within some bandwidth. + */ +static struct transponder *alloc_transponder(uint32_t frequency) +{ +	struct transponder *tp = calloc(1, sizeof(*tp)); + +	tp->param.frequency = frequency; +	INIT_LIST_HEAD(&tp->list); +	INIT_LIST_HEAD(&tp->services); +	list_add_tail(&tp->list, &new_transponders); +	return tp; +} + +static int is_same_transponder(uint32_t f1, uint32_t f2) +{ +	uint32_t diff; +	if (f1 == f2) +		return 1; +	diff = (f1 > f2) ? (f1 - f2) : (f2 - f1); +	//FIXME: use symbolrate etc. to estimate bandwidth +	if (diff < 2000) { +		debug("f1 = %u is same TP as f2 = %u\n", f1, f2); +		return 1; +	} +	return 0; +} + +static struct transponder *find_transponder(uint32_t frequency) +{ +	struct list_head *pos; +	struct transponder *tp; + +	list_for_each(pos, &scanned_transponders) { +		tp = list_entry(pos, struct transponder, list); +		if (is_same_transponder(tp->param.frequency, frequency)) +			return tp; +	} +	list_for_each(pos, &new_transponders) { +		tp = list_entry(pos, struct transponder, list); +		if (is_same_transponder(tp->param.frequency, frequency)) +			return tp; +	} +	return NULL; +} + +static void copy_transponder(struct transponder *d, struct transponder *s) +{ +	d->network_id = s->network_id; +	d->transport_stream_id = s->transport_stream_id; +	d->type = s->type; +	memcpy(&d->param, &s->param, sizeof(d->param)); +	d->polarisation = s->polarisation; +	d->orbital_pos = s->orbital_pos; +	d->we_flag = s->we_flag; +	d->scan_done = s->scan_done; +	d->last_tuning_failed = s->last_tuning_failed; +	d->other_frequency_flag = s->other_frequency_flag; +	d->n_other_f = s->n_other_f; +	if (d->n_other_f) { +		d->other_f = calloc(d->n_other_f, sizeof(uint32_t)); +		memcpy(d->other_f, s->other_f, d->n_other_f * sizeof(uint32_t)); +	} +	else +		d->other_f = NULL; +} + +/* service_ids are guaranteed to be unique within one TP + * (the DVB standards say theay should be unique within one + * network, but in real life...) + */ +static struct service *alloc_service(struct transponder *tp, int service_id) +{ +	struct service *s = calloc(1, sizeof(*s)); +	INIT_LIST_HEAD(&s->list); +	s->service_id = service_id; +	list_add_tail(&s->list, &tp->services); +	return s; +} + +static struct service *find_service(struct transponder *tp, int service_id) +{ +	struct list_head *pos; +	struct service *s; + +	list_for_each(pos, &tp->services) { +		s = list_entry(pos, struct service, list); +		if (s->service_id == service_id) +			return s; +	} +	return NULL; +} + + +static void parse_ca_identifier_descriptor (const unsigned char *buf, +				     struct service *s) +{ +	unsigned char len = buf [1]; +	int i; + +	buf += 2; + +	if (len > sizeof(s->ca_id)) { +		len = sizeof(s->ca_id); +		warning("too many CA system ids\n"); +	} +	memcpy(s->ca_id, buf, len); +	for (i = 0; i < len / sizeof(s->ca_id[0]); i++) +		moreverbose("  CA ID 0x%04x\n", s->ca_id[i]); +} + + +static void parse_iso639_language_descriptor (const unsigned char *buf, struct service *s) +{ +	unsigned char len = buf [1]; + +	buf += 2; + +	if (len >= 4) { +		debug("    LANG=%.3s %d\n", buf, buf[3]); +		memcpy(s->audio_lang[s->audio_num], buf, 3); +#if 0 +		/* seems like the audio_type is wrong all over the place */ +		//if (buf[3] == 0) -> normal +		if (buf[3] == 1) +			s->audio_lang[s->audio_num][3] = '!'; /* clean effects (no language) */ +		else if (buf[3] == 2) +			s->audio_lang[s->audio_num][3] = '?'; /* for the hearing impaired */ +		else if (buf[3] == 3) +			s->audio_lang[s->audio_num][3] = '+'; /* visually impaired commentary */ +#endif +	} +} + +static void parse_network_name_descriptor (const unsigned char *buf, void *dummy) +{ +	unsigned char len = buf [1]; + +	info("Network Name '%.*s'\n", len, buf + 2); +} + +static void parse_terrestrial_uk_channel_number (const unsigned char *buf, void *dummy) +{ +	int i, n, channel_num, service_id; +	struct list_head *p1, *p2; +	struct transponder *t; +	struct service *s; + +	// 32 bits per record +	n = buf[1] / 4; +	if (n < 1) +		return; + +	// desc id, desc len, (service id, service number) +	buf += 2; +	for (i = 0; i < n; i++) { +		service_id = (buf[0]<<8)|(buf[1]&0xff); +		channel_num = (buf[2]&0x03<<8)|(buf[3]&0xff); +		debug("Service ID 0x%x has channel number %d ", service_id, channel_num); +		list_for_each(p1, &scanned_transponders) { +			t = list_entry(p1, struct transponder, list); +			list_for_each(p2, &t->services) { +				s = list_entry(p2, struct service, list); +				if (s->service_id == service_id) +					s->channel_num = channel_num; +			} +		} +		buf += 4; +	} +} + + +static long bcd32_to_cpu (const int b0, const int b1, const int b2, const int b3) +{ +	return ((b0 >> 4) & 0x0f) * 10000000 + (b0 & 0x0f) * 1000000 + +	       ((b1 >> 4) & 0x0f) * 100000   + (b1 & 0x0f) * 10000 + +	       ((b2 >> 4) & 0x0f) * 1000     + (b2 & 0x0f) * 100 + +	       ((b3 >> 4) & 0x0f) * 10       + (b3 & 0x0f); +} + + +static const fe_code_rate_t fec_tab [8] = { +	FEC_AUTO, FEC_1_2, FEC_2_3, FEC_3_4, +	FEC_5_6, FEC_7_8, FEC_NONE, FEC_NONE +}; + + +static const fe_modulation_t qam_tab [6] = { +	QAM_AUTO, QAM_16, QAM_32, QAM_64, QAM_128, QAM_256 +}; + + +static void parse_cable_delivery_system_descriptor (const unsigned char *buf, +					     struct transponder *t) +{ +	if (!t) { +		warning("cable_delivery_system_descriptor outside transport stream definition (ignored)\n"); +		return; +	} +	t->type = FE_QAM; + +	t->param.frequency = bcd32_to_cpu (buf[2], buf[3], buf[4], buf[5]); +	t->param.frequency *= 100; +	t->param.u.qam.fec_inner = fec_tab[buf[12] & 0x07]; +	t->param.u.qam.symbol_rate = 10 * bcd32_to_cpu (buf[9], +							buf[10], +							buf[11], +							buf[12] & 0xf0); +	if ((buf[8] & 0x0f) > 5) +		t->param.u.qam.modulation = QAM_AUTO; +	else +		t->param.u.qam.modulation = qam_tab[buf[8] & 0x0f]; +	t->param.inversion = spectral_inversion; + +	if (verbosity >= 5) { +		debug("0x%#04x/0x%#04x ", t->network_id, t->transport_stream_id); +		dump_dvb_parameters (stderr, t); +		if (t->scan_done) +			dprintf(5, " (done)"); +		if (t->last_tuning_failed) +			dprintf(5, " (tuning failed)"); +		dprintf(5, "\n"); +	} +} + +static void parse_satellite_delivery_system_descriptor (const unsigned char *buf, +						 struct transponder *t) +{ +	if (!t) { +		warning("satellite_delivery_system_descriptor outside transport stream definition (ignored)\n"); +		return; +	} +	t->type = FE_QPSK; +	t->param.frequency = 10 * bcd32_to_cpu (buf[2], buf[3], buf[4], buf[5]); +	t->param.u.qpsk.fec_inner = fec_tab[buf[12] & 0x07]; +	t->param.u.qpsk.symbol_rate = 10 * bcd32_to_cpu (buf[9], +							 buf[10], +							 buf[11], +							 buf[12] & 0xf0); + +	t->polarisation = (buf[8] >> 5) & 0x03; +	t->param.inversion = spectral_inversion; + +	t->orbital_pos = bcd32_to_cpu (0x00, 0x00, buf[6], buf[7]); +	t->we_flag = buf[8] >> 7; + +	if (verbosity >= 5) { +		debug("0x%#04x/0x%#04x ", t->network_id, t->transport_stream_id); +		dump_dvb_parameters (stderr, t); +		if (t->scan_done) +			dprintf(5, " (done)"); +		if (t->last_tuning_failed) +			dprintf(5, " (tuning failed)"); +		dprintf(5, "\n"); +	} +} + + +static void parse_terrestrial_delivery_system_descriptor (const unsigned char *buf, +						   struct transponder *t) +{ +	static const fe_modulation_t m_tab [] = { QPSK, QAM_16, QAM_64, QAM_AUTO }; +	static const fe_code_rate_t ofec_tab [8] = { FEC_1_2, FEC_2_3, FEC_3_4, +					       FEC_5_6, FEC_7_8 }; +	struct dvb_ofdm_parameters *o; + +	if (!t) { +		warning("terrestrial_delivery_system_descriptor outside transport stream definition (ignored)\n"); +		return; +	} +	o = &t->param.u.ofdm; +	t->type = FE_OFDM; + +	t->param.frequency = (buf[2] << 24) | (buf[3] << 16); +	t->param.frequency |= (buf[4] << 8) | buf[5]; +	t->param.frequency *= 10; +	t->param.inversion = spectral_inversion; + +	o->bandwidth = BANDWIDTH_8_MHZ + ((buf[6] >> 5) & 0x3); +	o->constellation = m_tab[(buf[7] >> 6) & 0x3]; +	o->hierarchy_information = HIERARCHY_NONE + ((buf[7] >> 3) & 0x3); + +	if ((buf[7] & 0x7) > 4) +		o->code_rate_HP = FEC_AUTO; +	else +		o->code_rate_HP = ofec_tab [buf[7] & 0x7]; + +	if (((buf[8] >> 5) & 0x7) > 4) +		o->code_rate_LP = FEC_AUTO; +	else +		o->code_rate_LP = ofec_tab [(buf[8] >> 5) & 0x7]; + +	o->guard_interval = GUARD_INTERVAL_1_32 + ((buf[8] >> 3) & 0x3); + +	o->transmission_mode = (buf[8] & 0x2) ? +			       TRANSMISSION_MODE_8K : +			       TRANSMISSION_MODE_2K; + +	t->other_frequency_flag = (buf[8] & 0x01); + +	if (verbosity >= 5) { +		debug("0x%#04x/0x%#04x ", t->network_id, t->transport_stream_id); +		dump_dvb_parameters (stderr, t); +		if (t->scan_done) +			dprintf(5, " (done)"); +		if (t->last_tuning_failed) +			dprintf(5, " (tuning failed)"); +		dprintf(5, "\n"); +	} +} + +static void parse_frequency_list_descriptor (const unsigned char *buf, +				      struct transponder *t) +{ +	int n, i; +	typeof(*t->other_f) f; + +	if (!t) { +		warning("frequency_list_descriptor outside transport stream definition (ignored)\n"); +		return; +	} +	if (t->other_f) +		return; + +	n = (buf[1] - 1) / 4; +	if (n < 1 || (buf[2] & 0x03) != 3) +		return; + +	t->other_f = calloc(n, sizeof(*t->other_f)); +	t->n_other_f = n; +	buf += 3; +	for (i = 0; i < n; i++) { +		f = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; +		t->other_f[i] = f * 10; +		buf += 4; +	} +} + +static void parse_service_descriptor (const unsigned char *buf, struct service *s) +{ +	unsigned char len; +	unsigned char *src, *dest; + +	s->type = buf[2]; + +	buf += 3; +	len = *buf; +	buf++; + +	if (s->provider_name) +		free (s->provider_name); + +	s->provider_name = malloc (len + 1); +	memcpy (s->provider_name, buf, len); +	s->provider_name[len] = '\0'; + +	/* remove control characters (FIXME: handle short/long name) */ +	/* FIXME: handle character set correctly (e.g. via iconv) +	 * c.f. EN 300 468 annex A */ +	for (src = dest = s->provider_name; *src; src++) +		if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f)) +			*dest++ = *src; +	*dest = '\0'; +	if (!s->provider_name[0]) { +		/* zap zero length names */ +		free (s->provider_name); +		s->provider_name = 0; +	} + +	if (s->service_name) +		free (s->service_name); + +	buf += len; +	len = *buf; +	buf++; + +	s->service_name = malloc (len + 1); +	memcpy (s->service_name, buf, len); +	s->service_name[len] = '\0'; + +	/* remove control characters (FIXME: handle short/long name) */ +	/* FIXME: handle character set correctly (e.g. via iconv) +	 * c.f. EN 300 468 annex A */ +	for (src = dest = s->service_name; *src; src++) +		if (*src >= 0x20 && (*src < 0x80 || *src > 0x9f)) +			*dest++ = *src; +	*dest = '\0'; +	if (!s->service_name[0]) { +		/* zap zero length names */ +		free (s->service_name); +		s->service_name = 0; +	} + +	info("0x%04x 0x%04x: pmt_pid 0x%04x %s -- %s (%s%s)\n", +	    s->transport_stream_id, +	    s->service_id, +	    s->pmt_pid, +	    s->provider_name, s->service_name, +	    s->running == RM_NOT_RUNNING ? "not running" : +	    s->running == RM_STARTS_SOON ? "starts soon" : +	    s->running == RM_PAUSING     ? "pausing" : +	    s->running == RM_RUNNING     ? "running" : "???", +	    s->scrambled ? ", scrambled" : ""); +} + +static int find_descriptor(uint8_t tag, const unsigned char *buf, +		int descriptors_loop_len, +		const unsigned char **desc, int *desc_len) +{ +	while (descriptors_loop_len > 0) { +		unsigned char descriptor_tag = buf[0]; +		unsigned char descriptor_len = buf[1] + 2; + +		if (!descriptor_len) { +			warning("descriptor_tag == 0x%02x, len is 0\n", descriptor_tag); +			break; +		} + +		if (tag == descriptor_tag) { +			if (desc) +				*desc = buf; +			if (desc_len) +				*desc_len = descriptor_len; +			return 1; +		} + +		buf += descriptor_len; +		descriptors_loop_len -= descriptor_len; +	} +	return 0; +} + +static void parse_descriptors(enum table_type t, const unsigned char *buf, +			      int descriptors_loop_len, void *data) +{ +	while (descriptors_loop_len > 0) { +		unsigned char descriptor_tag = buf[0]; +		unsigned char descriptor_len = buf[1] + 2; + +		if (!descriptor_len) { +			warning("descriptor_tag == 0x%02x, len is 0\n", descriptor_tag); +			break; +		} + +		switch (descriptor_tag) { +		case 0x0a: +			if (t == PMT) +				parse_iso639_language_descriptor (buf, data); +			break; + +		case 0x40: +			if (t == NIT) +				parse_network_name_descriptor (buf, data); +			break; + +		case 0x43: +			if (t == NIT) +				parse_satellite_delivery_system_descriptor (buf, data); +			break; + +		case 0x44: +			if (t == NIT) +				parse_cable_delivery_system_descriptor (buf, data); +			break; + +		case 0x48: +			if (t == SDT) +				parse_service_descriptor (buf, data); +			break; + +		case 0x53: +			if (t == SDT) +				parse_ca_identifier_descriptor (buf, data); +			break; + +		case 0x5a: +			if (t == NIT) +				parse_terrestrial_delivery_system_descriptor (buf, data); +			break; + +		case 0x62: +			if (t == NIT) +				parse_frequency_list_descriptor (buf, data); +			break; + +		case 0x83: +			/* 0x83 is in the privately defined range of descriptor tags, +			 * so we parse this only if the user says so to avoid +			 * problems when 0x83 is something entirely different... */ +			if (t == NIT && vdr_dump_channum) +				parse_terrestrial_uk_channel_number (buf, data); +			break; + +		default: +			verbosedebug("skip descriptor 0x%02x\n", descriptor_tag); +		}; + +		buf += descriptor_len; +		descriptors_loop_len -= descriptor_len; +	} +} + + +static void parse_pat(const unsigned char *buf, int section_length, +		      int transport_stream_id) +{ +	while (section_length > 0) { +		struct service *s; +		int service_id = (buf[0] << 8) | buf[1]; + +		if (service_id == 0) { +			buf += 4;		/*  skip nit pid entry... */ +			section_length -= 4; +			continue; +		} +		/* SDT might have been parsed first... */ +		s = find_service(current_tp, service_id); +		if (!s) +			s = alloc_service(current_tp, service_id); +		s->pmt_pid = ((buf[2] & 0x1f) << 8) | buf[3]; +		if (!s->priv && s->pmt_pid) { +			s->priv = malloc(sizeof(struct section_buf)); +			setup_filter(s->priv, demux_devname, +				     s->pmt_pid, 0x02, 1, 0, 5); + +			add_filter (s->priv); +		} + +		buf += 4; +		section_length -= 4; +	}; +} + + +static void parse_pmt (const unsigned char *buf, int section_length, int service_id) +{ +	int program_info_len; +	struct service *s; +        char msg_buf[14 * AUDIO_CHAN_MAX + 1]; +        char *tmp; +        int i; + +	s = find_service (current_tp, service_id); +	if (!s) { +		error("PMT for serivce_id 0x%04x was not in PAT\n", service_id); +		return; +	} + +	s->pcr_pid = ((buf[0] & 0x1f) << 8) | buf[1]; + +	program_info_len = ((buf[2] & 0x0f) << 8) | buf[3]; + +	buf += program_info_len + 4; +	section_length -= program_info_len + 4; + +	while (section_length > 0) { +		int ES_info_len = ((buf[3] & 0x0f) << 8) | buf[4]; +		int elementary_pid = ((buf[1] & 0x1f) << 8) | buf[2]; + +		switch (buf[0]) { +		case 0x01: +		case 0x02: +			moreverbose("  VIDEO     : PID 0x%04x\n", elementary_pid); +			if (s->video_pid == 0) +				s->video_pid = elementary_pid; +			break; +		case 0x03: +		case 0x04: +			moreverbose("  AUDIO     : PID 0x%04x\n", elementary_pid); +			if (s->audio_num < AUDIO_CHAN_MAX) { +				s->audio_pid[s->audio_num] = elementary_pid; +				parse_descriptors (PMT, buf + 5, ES_info_len, s); +				s->audio_num++; +			} +			else +				warning("more than %i audio channels, truncating\n", +				     AUDIO_CHAN_MAX); +			break; +		case 0x06: +			if (find_descriptor(0x56, buf + 5, ES_info_len, NULL, NULL)) { +				moreverbose("  TELETEXT  : PID 0x%04x\n", elementary_pid); +				s->teletext_pid = elementary_pid; +				break; +			} +			else if (find_descriptor(0x59, buf + 5, ES_info_len, NULL, NULL)) { +				/* Note: The subtitling descriptor can also signal +				 * teletext subtitling, but then the teletext descriptor +				 * will also be present; so we can be quite confident +				 * that we catch DVB subtitling streams only here, w/o +				 * parsing the descriptor. */ +				moreverbose("  SUBTITLING: PID 0x%04x\n", elementary_pid); +				s->subtitling_pid = elementary_pid; +				break; +			} +			else if (find_descriptor(0x6a, buf + 5, ES_info_len, NULL, NULL)) { +				moreverbose("  AC3       : PID 0x%04x\n", elementary_pid); +				s->ac3_pid = elementary_pid; +				break; +			} +			/* fall through */ +		default: +			moreverbose("  OTHER     : PID 0x%04x TYPE 0x%02x\n", elementary_pid, buf[0]); +		}; + +		buf += ES_info_len + 5; +		section_length -= ES_info_len + 5; +	}; + + +        tmp = msg_buf; +        tmp += sprintf(tmp, "0x%04x (%.4s)", s->audio_pid[0], s->audio_lang[0]); + +	if (s->audio_num > AUDIO_CHAN_MAX) { +		warning("more than %i audio channels: %i, truncating to %i\n", +		      AUDIO_CHAN_MAX, s->audio_num, AUDIO_CHAN_MAX); +		s->audio_num = AUDIO_CHAN_MAX; +	} + +        for (i=1; i<s->audio_num; i++) +                tmp += sprintf(tmp, ", 0x%04x (%.4s)", s->audio_pid[i], s->audio_lang[i]); + +        debug("0x%04x 0x%04x: %s -- %s, pmt_pid 0x%04x, vpid 0x%04x, apid %s\n", +	    s->transport_stream_id, +	    s->service_id, +	    s->provider_name, s->service_name, +	    s->pmt_pid, s->video_pid, msg_buf); +} + + +static void parse_nit (const unsigned char *buf, int section_length, int network_id) +{ +	int descriptors_loop_len = ((buf[0] & 0x0f) << 8) | buf[1]; + +	if (section_length < descriptors_loop_len + 4) +	{ +		warning("section too short: network_id == 0x%04x, section_length == %i, " +		     "descriptors_loop_len == %i\n", +		     network_id, section_length, descriptors_loop_len); +		return; +	} + +	parse_descriptors (NIT, buf + 2, descriptors_loop_len, NULL); + +	section_length -= descriptors_loop_len + 4; +	buf += descriptors_loop_len + 4; + +	while (section_length > 6) { +		int transport_stream_id = (buf[0] << 8) | buf[1]; +		struct transponder *t, tn; + +		descriptors_loop_len = ((buf[4] & 0x0f) << 8) | buf[5]; + +		if (section_length < descriptors_loop_len + 4) +		{ +			warning("section too short: transport_stream_id == 0x%04x, " +			     "section_length == %i, descriptors_loop_len == %i\n", +			     transport_stream_id, section_length, +			     descriptors_loop_len); +			break; +		} + +		debug("transport_stream_id 0x%04x\n", transport_stream_id); + +		memset(&tn, 0, sizeof(tn)); +		tn.type = -1; +		tn.network_id = network_id; +		tn.transport_stream_id = transport_stream_id; + +		parse_descriptors (NIT, buf + 6, descriptors_loop_len, &tn); + +		if (tn.type == fe_info.type) { +			/* only add if develivery_descriptor matches FE type */ +			t = find_transponder(tn.param.frequency); +			if (!t) +				t = alloc_transponder(tn.param.frequency); +			copy_transponder(t, &tn); +		} + +		section_length -= descriptors_loop_len + 6; +		buf += descriptors_loop_len + 6; +	}; +} + + +static void parse_sdt (const unsigned char *buf, int section_length, +		int transport_stream_id) +{ +	buf += 3;	       /*  skip original network id + reserved field */ + +	while (section_length > 4) { +		int service_id = (buf[0] << 8) | buf[1]; +		int descriptors_loop_len = ((buf[3] & 0x0f) << 8) | buf[4]; +		struct service *s; + +		if (section_length < descriptors_loop_len || !descriptors_loop_len) +		{ +			warning("section too short: service_id == 0x%02x, section_length == %i, " +			     "descriptors_loop_len == %i\n", +			     service_id, section_length, +			     descriptors_loop_len); +			break; +		} + +		s = find_service(current_tp, service_id); +		if (!s) +			/* maybe PAT has not yet been parsed... */ +			s = alloc_service(current_tp, service_id); + +		s->running = (buf[3] >> 5) & 0x7; +		s->scrambled = (buf[3] >> 4) & 1; + +		parse_descriptors (SDT, buf + 5, descriptors_loop_len, s); + +		section_length -= descriptors_loop_len + 5; +		buf += descriptors_loop_len + 5; +	}; +} + + +static int get_bit (uint8_t *bitfield, int bit) +{ +	return (bitfield[bit/8] >> (bit % 8)) & 1; +} + +static void set_bit (uint8_t *bitfield, int bit) +{ +	bitfield[bit/8] |= 1 << (bit % 8); +} + + +/** + *   returns 0 when more sections are expected + *	   1 when all sections are read on this pid + *	   -1 on invalid table id + */ +static int parse_section (struct section_buf *s) +{ +	const unsigned char *buf = s->buf; +	int table_id; +	int section_length; +	int table_id_ext; +	int section_version_number; +	int section_number; +	int last_section_number; +	int i; + +	table_id = buf[0]; + +	if (s->table_id != table_id) +		return -1; + +	section_length = (((buf[1] & 0x0f) << 8) | buf[2]) - 11; + +	table_id_ext = (buf[3] << 8) | buf[4]; +	section_version_number = (buf[5] >> 1) & 0x1f; +	section_number = buf[6]; +	last_section_number = buf[7]; + +	if (s->segmented && s->table_id_ext != -1 && s->table_id_ext != table_id_ext) { +		/* find or allocate actual section_buf matching table_id_ext */ +		while (s->next_seg) { +			s = s->next_seg; +			if (s->table_id_ext == table_id_ext) +				break; +		} +		if (s->table_id_ext != table_id_ext) { +			assert(s->next_seg == NULL); +			s->next_seg = calloc(1, sizeof(struct section_buf)); +			s->next_seg->segmented = s->segmented; +			s->next_seg->run_once = s->run_once; +			s->next_seg->timeout = s->timeout; +			s = s->next_seg; +			s->table_id = table_id; +			s->table_id_ext = table_id_ext; +			s->section_version_number = section_version_number; +		} +	} + +	if (s->section_version_number != section_version_number || +			s->table_id_ext != table_id_ext) { +		struct section_buf *next_seg = s->next_seg; + +		if (s->section_version_number != -1 && s->table_id_ext != -1) +			debug("section version_number or table_id_ext changed " +				"%d -> %d / %04x -> %04x\n", +				s->section_version_number, section_version_number, +				s->table_id_ext, table_id_ext); +		s->table_id_ext = table_id_ext; +		s->section_version_number = section_version_number; +		s->sectionfilter_done = 0; +		memset (s->section_done, 0, sizeof(s->section_done)); +		s->next_seg = next_seg; +	} + +	buf += 8; + +	if (!get_bit(s->section_done, section_number)) { +		set_bit (s->section_done, section_number); + +		debug("pid 0x%02x tid 0x%02x table_id_ext 0x%04x, " +		    "%i/%i (version %i)\n", +		    s->pid, table_id, table_id_ext, section_number, +		    last_section_number, section_version_number); + +		switch (table_id) { +		case 0x00: +			verbose("PAT\n"); +			parse_pat (buf, section_length, table_id_ext); +			break; + +		case 0x02: +			verbose("PMT 0x%04x for service 0x%04x\n", s->pid, table_id_ext); +			parse_pmt (buf, section_length, table_id_ext); +			break; + +		case 0x41: +			verbose("////////////////////////////////////////////// NIT other\n"); +		case 0x40: +			verbose("NIT (%s TS)\n", table_id == 0x40 ? "actual":"other"); +			parse_nit (buf, section_length, table_id_ext); +			break; + +		case 0x42: +		case 0x46: +			verbose("SDT (%s TS)\n", table_id == 0x42 ? "actual":"other"); +			parse_sdt (buf, section_length, table_id_ext); +			break; + +		default: +			; +		}; + +		for (i = 0; i <= last_section_number; i++) +			if (get_bit (s->section_done, i) == 0) +				break; + +		if (i > last_section_number) +			s->sectionfilter_done = 1; +	} + +	if (s->segmented) { +		/* always wait for timeout; this is because we don't now how +		 * many segments there are +		 */ +		return 0; +	} +	else if (s->sectionfilter_done) +		return 1; + +	return 0; +} + + +static int read_sections (struct section_buf *s) +{ +	int section_length, count; + +	if (s->sectionfilter_done && !s->segmented) +		return 1; + +	/* the section filter API guarantess that we get one full section +	 * per read(), provided that the buffer is large enough (it is) +	 */ +	if (((count = read (s->fd, s->buf, sizeof(s->buf))) < 0) && errno == EOVERFLOW) +		count = read (s->fd, s->buf, sizeof(s->buf)); +	if (count < 0) { +		errorn("read_sections: read error"); +		return -1; +	} + +	if (count < 4) +		return -1; + +	section_length = ((s->buf[1] & 0x0f) << 8) | s->buf[2]; + +	if (count != section_length + 3) +		return -1; + +	if (parse_section(s) == 1) +		return 1; + +	return 0; +} + + +static LIST_HEAD(running_filters); +static LIST_HEAD(waiting_filters); +static int n_running; +#define MAX_RUNNING 32 +static struct pollfd poll_fds[MAX_RUNNING]; +static struct section_buf* poll_section_bufs[MAX_RUNNING]; + + +static void setup_filter (struct section_buf* s, const char *dmx_devname, +			  int pid, int tid, int run_once, int segmented, int timeout) +{ +	memset (s, 0, sizeof(struct section_buf)); + +	s->fd = -1; +	s->dmx_devname = dmx_devname; +	s->pid = pid; +	s->table_id = tid; + +	s->run_once = run_once; +	s->segmented = segmented; + +	if (long_timeout) +		s->timeout = 5 * timeout; +	else +		s->timeout = timeout; + +	s->table_id_ext = -1; +	s->section_version_number = -1; + +	INIT_LIST_HEAD (&s->list); +} + +static void update_poll_fds(void) +{ +	struct list_head *p; +	struct section_buf* s; +	int i; + +	memset(poll_section_bufs, 0, sizeof(poll_section_bufs)); +	for (i = 0; i < MAX_RUNNING; i++) +		poll_fds[i].fd = -1; +	i = 0; +	list_for_each (p, &running_filters) { +		if (i >= MAX_RUNNING) +			fatal("too many poll_fds\n"); +		s = list_entry (p, struct section_buf, list); +		if (s->fd == -1) +			fatal("s->fd == -1 on running_filters\n"); +		verbosedebug("poll fd %d\n", s->fd); +		poll_fds[i].fd = s->fd; +		poll_fds[i].events = POLLIN; +		poll_fds[i].revents = 0; +		poll_section_bufs[i] = s; +		i++; +	} +	if (i != n_running) +		fatal("n_running is hosed\n"); +} + +static int start_filter (struct section_buf* s) +{ +	struct dmx_sct_filter_params f; + +	if (n_running >= MAX_RUNNING) +		goto err0; +	if ((s->fd = open (s->dmx_devname, O_RDWR | O_NONBLOCK)) < 0) +		goto err0; + +	verbosedebug("start filter pid 0x%04x table_id 0x%02x\n", s->pid, s->table_id); + +	memset(&f, 0, sizeof(f)); + +	f.pid = (uint16_t) s->pid; + +	if (s->table_id < 0x100 && s->table_id > 0) { +		f.filter.filter[0] = (uint8_t) s->table_id; +		f.filter.mask[0]   = 0xff; +	} + +	f.timeout = 0; +	f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC; + +	if (ioctl(s->fd, DMX_SET_FILTER, &f) == -1) { +		errorn ("ioctl DMX_SET_FILTER failed"); +		goto err1; +	} + +	s->sectionfilter_done = 0; +	time(&s->start_time); + +	list_del_init (&s->list);  /* might be in waiting filter list */ +	list_add (&s->list, &running_filters); + +	n_running++; +	update_poll_fds(); + +	return 0; + +err1: +	ioctl (s->fd, DMX_STOP); +	close (s->fd); +err0: +	return -1; +} + + +static void stop_filter (struct section_buf *s) +{ +	verbosedebug("stop filter pid 0x%04x\n", s->pid); +	ioctl (s->fd, DMX_STOP); +	close (s->fd); +	s->fd = -1; +	list_del (&s->list); +	s->running_time += time(NULL) - s->start_time; + +	n_running--; +	update_poll_fds(); +} + + +static void add_filter (struct section_buf *s) +{ +	verbosedebug("add filter pid 0x%04x\n", s->pid); +	if (start_filter (s)) +		list_add_tail (&s->list, &waiting_filters); +} + + +static void remove_filter (struct section_buf *s) +{ +	verbosedebug("remove filter pid 0x%04x\n", s->pid); +	stop_filter (s); + +	while (!list_empty(&waiting_filters)) { +		struct list_head *next = waiting_filters.next; +		s = list_entry (next, struct section_buf, list); +		if (start_filter (s)) +			break; +	}; +} + + +static void read_filters (void) +{ +	struct section_buf *s; +	int i, n, done; + +	n = poll(poll_fds, n_running, 1000); +	if (n == -1) +		errorn("poll"); + +	for (i = 0; i < n_running; i++) { +		s = poll_section_bufs[i]; +		if (!s) +			fatal("poll_section_bufs[%d] is NULL\n", i); +		if (poll_fds[i].revents) +			done = read_sections (s) == 1; +		else +			done = 0; /* timeout */ +		if (done || time(NULL) > s->start_time + s->timeout) { +			if (s->run_once) { +				if (done) +					verbosedebug("filter done pid 0x%04x\n", s->pid); +				else +					warning("filter timeout pid 0x%04x\n", s->pid); +				remove_filter (s); +			} +		} +	} +} + + +static int mem_is_zero (const void *mem, int size) +{ +	const char *p = mem; +	unsigned long i; + +	for (i=0; i<size; i++) { +		if (p[i] != 0x00) +			return 0; +	} + +	return 1; +} + + +static int switch_pos = 0; + +static int __tune_to_transponder (int frontend_fd, struct transponder *t) +{ +	struct dvb_frontend_parameters p; +	fe_status_t s; +	int i; + +	current_tp = t; + +	if (mem_is_zero (&t->param, sizeof(struct dvb_frontend_parameters))) +		return -1; + +	memcpy (&p, &t->param, sizeof(struct dvb_frontend_parameters)); + +	if (verbosity >= 1) { +		dprintf(1, ">>> tune to: "); +		dump_dvb_parameters (stderr, t); +		if (t->last_tuning_failed) +			dprintf(1, " (tuning failed)"); +		dprintf(1, "\n"); +	} + +	if (t->type == FE_QPSK) { +		int hiband = 0; + +		if (lnb_type.switch_val && lnb_type.high_val && +			p.frequency >= lnb_type.switch_val) +			hiband = 1; + +		setup_switch (frontend_fd, +			      switch_pos, +			      t->polarisation == POLARISATION_VERTICAL ? 0 : 1, +			      hiband); +		usleep(50000); +		if (hiband) +			p.frequency = abs(p.frequency - lnb_type.high_val); +		else +			p.frequency = abs(p.frequency - lnb_type.low_val); +	} + +	if (ioctl(frontend_fd, FE_SET_FRONTEND, &p) == -1) { +		errorn("Setting frontend parameters failed"); +		return -1; +	} + +	for (i = 0; i < 10; i++) { +		usleep (200000); + +		if (ioctl(frontend_fd, FE_READ_STATUS, &s) == -1) { +			errorn("FE_READ_STATUS failed"); +			return -1; +		} + +		verbose(">>> tuning status == 0x%02x\n", s); + +		if (s & FE_HAS_LOCK) { +			t->last_tuning_failed = 0; +			return 0; +		} +	} + +	warning(">>> tuning failed!!!\n"); + +	t->last_tuning_failed = 1; + +	return -1; +} + +static int tune_to_transponder (int frontend_fd, struct transponder *t) +{ +	/* move TP from "new" to "scanned" list */ +	list_del_init(&t->list); +	list_add_tail(&t->list, &scanned_transponders); +	t->scan_done = 1; + +	if (t->type != fe_info.type) { +		/* ignore cable descriptors in sat NIT and vice versa */ +		t->last_tuning_failed = 1; +		return -1; +	} + +	if (__tune_to_transponder (frontend_fd, t) == 0) +		return 0; + +	return __tune_to_transponder (frontend_fd, t); +} + + +static int tune_to_next_transponder (int frontend_fd) +{ +	struct list_head *pos, *tmp; +	struct transponder *t; + +	list_for_each_safe(pos, tmp, &new_transponders) { +		t = list_entry (pos, struct transponder, list); +retry: +		if (tune_to_transponder (frontend_fd, t) == 0) +			return 0; +		if (t->other_frequency_flag && +				t->other_f && +				t->n_other_f) { +			t->param.frequency = t->other_f[t->n_other_f - 1]; +			t->n_other_f--; +			info("retrying with f=%d\n", t->param.frequency); +			goto retry; +		} +	} +	return -1; +} + +struct strtab { +	const char *str; +	int val; +}; +static int str2enum(const char *str, const struct strtab *tab, int deflt) +{ +	while (tab->str) { +		if (!strcmp(tab->str, str)) +			return tab->val; +		tab++; +	} +	error("invalid enum value '%s'\n", str); +	return deflt; +} + +static enum fe_code_rate str2fec(const char *fec) +{ +	struct strtab fectab[] = { +		{ "NONE", FEC_NONE }, +		{ "1/2",  FEC_1_2 }, +		{ "2/3",  FEC_2_3 }, +		{ "3/4",  FEC_3_4 }, +		{ "4/5",  FEC_4_5 }, +		{ "5/6",  FEC_5_6 }, +		{ "6/7",  FEC_6_7 }, +		{ "7/8",  FEC_7_8 }, +		{ "8/9",  FEC_8_9 }, +		{ "AUTO", FEC_AUTO }, +		{ NULL, 0 } +	}; +	return str2enum(fec, fectab, FEC_AUTO); +} + +static enum fe_modulation str2qam(const char *qam) +{ +	struct strtab qamtab[] = { +		{ "QPSK",   QPSK }, +		{ "QAM16",  QAM_16 }, +		{ "QAM32",  QAM_32 }, +		{ "QAM64",  QAM_64 }, +		{ "QAM128", QAM_128 }, +		{ "QAM256", QAM_256 }, +		{ "AUTO",   QAM_AUTO }, +		{ NULL, 0 } +	}; +	return str2enum(qam, qamtab, QAM_AUTO); +} + +static enum fe_bandwidth str2bandwidth(const char *bw) +{ +	struct strtab bwtab[] = { +		{ "8MHz", BANDWIDTH_8_MHZ }, +		{ "7MHz", BANDWIDTH_7_MHZ }, +		{ "6MHz", BANDWIDTH_6_MHZ }, +		{ "AUTO", BANDWIDTH_AUTO }, +		{ NULL, 0 } +	}; +	return str2enum(bw, bwtab, BANDWIDTH_AUTO); +} + +static enum fe_transmit_mode str2mode(const char *mode) +{ +	struct strtab modetab[] = { +		{ "2k",   TRANSMISSION_MODE_2K }, +		{ "8k",   TRANSMISSION_MODE_8K }, +		{ "AUTO", TRANSMISSION_MODE_AUTO }, +		{ NULL, 0 } +	}; +	return str2enum(mode, modetab, TRANSMISSION_MODE_AUTO); +} + +static enum fe_guard_interval str2guard(const char *guard) +{ +	struct strtab guardtab[] = { +		{ "1/32", GUARD_INTERVAL_1_32 }, +		{ "1/16", GUARD_INTERVAL_1_16 }, +		{ "1/8",  GUARD_INTERVAL_1_8 }, +		{ "1/4",  GUARD_INTERVAL_1_4 }, +		{ "AUTO", GUARD_INTERVAL_AUTO }, +		{ NULL, 0 } +	}; +	return str2enum(guard, guardtab, GUARD_INTERVAL_AUTO); +} + +static enum fe_hierarchy str2hier(const char *hier) +{ +	struct strtab hiertab[] = { +		{ "NONE", HIERARCHY_NONE }, +		{ "1",    HIERARCHY_1 }, +		{ "2",    HIERARCHY_2 }, +		{ "4",    HIERARCHY_4 }, +		{ "AUTO", HIERARCHY_AUTO }, +		{ NULL, 0 } +	}; +	return str2enum(hier, hiertab, HIERARCHY_AUTO); +} + +static int tune_initial (int frontend_fd, const char *initial) +{ +	FILE *inif; +	unsigned int f, sr; +	char buf[200]; +	char pol[20], fec[20], qam[20], bw[20], fec2[20], mode[20], guard[20], hier[20]; +	struct transponder *t; + +	inif = fopen(initial, "r"); +	if (!inif) { +		error("cannot open '%s': %d %m\n", initial, errno); +		return -1; +	} +	while (fgets(buf, sizeof(buf), inif)) { +		if (buf[0] == '#' || buf[0] == '\n') +			; +		else if (sscanf(buf, "S %u %1[HVLR] %u %4s\n", &f, pol, &sr, fec) == 4) { +			t = alloc_transponder(f); +			t->type = FE_QPSK; +			switch(pol[0]) { +				case 'H': +				case 'L': +					t->polarisation = POLARISATION_HORIZONTAL; +					break; +				default: +					t->polarisation = POLARISATION_VERTICAL;; +					break; +			} +			t->param.inversion = spectral_inversion; +			t->param.u.qpsk.symbol_rate = sr; +			t->param.u.qpsk.fec_inner = str2fec(fec); +			info("initial transponder %u %c %u %d\n", +					t->param.frequency, +					pol[0], sr, +					t->param.u.qpsk.fec_inner); +		} +		else if (sscanf(buf, "C %u %u %4s %6s\n", &f, &sr, fec, qam) == 4) { +			t = alloc_transponder(f); +			t->type = FE_QAM; +			t->param.inversion = spectral_inversion; +			t->param.u.qam.symbol_rate = sr; +			t->param.u.qam.fec_inner = str2fec(fec); +			t->param.u.qam.modulation = str2qam(qam); +			info("initial transponder %u %u %d %d\n", +					t->param.frequency, +					sr, +					t->param.u.qam.fec_inner, +					t->param.u.qam.modulation); +		} +		else if (sscanf(buf, "T %u %4s %4s %4s %7s %4s %4s %4s\n", +					&f, bw, fec, fec2, qam, mode, guard, hier) == 8) { +			t = alloc_transponder(f); +			t->type = FE_OFDM; +			t->param.inversion = spectral_inversion; +			t->param.u.ofdm.bandwidth = str2bandwidth(bw); +			t->param.u.ofdm.code_rate_HP = str2fec(fec); +			t->param.u.ofdm.code_rate_LP = str2fec(fec2); +			t->param.u.ofdm.constellation = str2qam(qam); +			t->param.u.ofdm.transmission_mode = str2mode(mode); +			t->param.u.ofdm.guard_interval = str2guard(guard); +			t->param.u.ofdm.hierarchy_information = str2hier(hier); +			info("initial transponder %u %d %d %d %d %d %d %d\n", +					t->param.frequency, +					t->param.u.ofdm.bandwidth, +					t->param.u.ofdm.code_rate_HP, +					t->param.u.ofdm.code_rate_LP, +					t->param.u.ofdm.constellation, +					t->param.u.ofdm.transmission_mode, +					t->param.u.ofdm.guard_interval, +					t->param.u.ofdm.hierarchy_information); +		} +		else +			error("cannot parse'%s'\n", buf); +	} + +	fclose(inif); + +	return tune_to_next_transponder(frontend_fd); +} + + +static void scan_tp (void) +{ +	struct section_buf s0; +	struct section_buf s1; +	struct section_buf s2; +	struct section_buf s3; + +	/** +	 *  filter timeouts > min repetition rates specified in ETR211 +	 */ +	setup_filter (&s0, demux_devname, 0x00, 0x00, 1, 0, 5); /* PAT */ +	setup_filter (&s1, demux_devname, 0x11, 0x42, 1, 0, 5); /* SDT */ + +	add_filter (&s0); +	add_filter (&s1); + +	if (!current_tp_only || output_format != OUTPUT_PIDS) { +		setup_filter (&s2, demux_devname, 0x10, 0x40, 1, 0, 15); /* NIT */ +		add_filter (&s2); +		if (get_other_nits) { +			/* get NIT-others +			 * Note: There is more than one NIT-other: one per +			 * network, separated by the network_id. +			 */ +			setup_filter (&s3, demux_devname, 0x10, 0x41, 1, 1, 15); +			add_filter (&s3); +		} +	} + +	do { +		read_filters (); +	} while (!(list_empty(&running_filters) && +		   list_empty(&waiting_filters))); +} + +static void scan_network (int frontend_fd, const char *initial) +{ +	if (tune_initial (frontend_fd, initial) < 0) { +		error("initial tuning failed\n"); +		return; +	} + +	do { +		scan_tp(); +	} while (tune_to_next_transponder(frontend_fd) == 0); +} + + +static void pids_dump_service_parameter_set(FILE *f, struct service *s) +{ +        int i; + +	fprintf(f, "%-24.24s (0x%04x) %02x: ", s->service_name, s->service_id, s->type); +	if (!s->pcr_pid || (s->type > 2)) +		fprintf(f, "           "); +	else if (s->pcr_pid == s->video_pid) +		fprintf(f, "PCR == V   "); +	else if ((s->audio_num == 1) && (s->pcr_pid == s->audio_pid[0])) +		fprintf(f, "PCR == A   "); +	else +		fprintf(f, "PCR 0x%04x ", s->pcr_pid); +	if (s->video_pid) +		fprintf(f, "V 0x%04x", s->video_pid); +	else +		fprintf(f, "        "); +	if (s->audio_num) +		fprintf(f, " A"); +        for (i = 0; i < s->audio_num; i++) { +		fprintf(f, " 0x%04x", s->audio_pid[i]); +		if (s->audio_lang[i][0]) +			fprintf(f, " (%.3s)", s->audio_lang[i]); +		else if (s->audio_num == 1) +			fprintf(f, "      "); +	} +	if (s->teletext_pid) +		fprintf(f, " TT 0x%04x", s->teletext_pid); +	if (s->ac3_pid) +		fprintf(f, " AC3 0x%04x", s->ac3_pid); +	if (s->subtitling_pid) +		fprintf(f, " SUB 0x%04x", s->subtitling_pid); +	fprintf(f, "\n"); +} + +static char sat_polarisation (struct transponder *t) +{ +	return t->polarisation == POLARISATION_VERTICAL ? 'v' : 'h'; +} + +static int sat_number (struct transponder *t) +{ +	return switch_pos; +} + +static void dump_lists (void) +{ +	struct list_head *p1, *p2; +	struct transponder *t; +	struct service *s; +	int n = 0, i; +	char sn[20]; + +	list_for_each(p1, &scanned_transponders) { +		t = list_entry(p1, struct transponder, list); +		list_for_each(p2, &t->services) { +			n++; +		} +	} +	info("dumping lists (%d services)\n", n); + +	list_for_each(p1, &scanned_transponders) { +		t = list_entry(p1, struct transponder, list); +		list_for_each(p2, &t->services) { +			s = list_entry(p2, struct service, list); + +			if (!s->service_name) { +				/* not in SDT */ +				snprintf(sn, sizeof(sn), "[%04x]", s->service_id); +				s->service_name = strdup(sn); +			} +			/* ':' is field separator in szap and vdr service lists */ +			for (i = 0; s->service_name[i]; i++) { +				if (s->service_name[i] == ':') +					s->service_name[i] = ' '; +			} +			for (i = 0; s->provider_name && s->provider_name[i]; i++) { +				if (s->provider_name[i] == ':') +					s->provider_name[i] = ' '; +			} +			if (s->video_pid && !(serv_select & 1)) +				continue; /* no TV services */ +			if (!s->video_pid && s->audio_num && !(serv_select & 2)) +				continue; /* no radio services */ +			if (!s->video_pid && !s->audio_num && !(serv_select & 4)) +				continue; /* no data/other services */ +			if (s->scrambled && !ca_select) +				continue; /* FTA only */ +			switch (output_format) +			{ +			  case OUTPUT_PIDS: +				pids_dump_service_parameter_set (stdout, s); +				break; +			  case OUTPUT_VDR: +				vdr_dump_service_parameter_set (stdout, +						    s->service_name, +						    s->provider_name, +						    t->type, +						    &t->param, +						    sat_polarisation(t), +						    s->video_pid, +						    s->pcr_pid, +						    s->audio_pid, +						    //FIXME: s->audio_lang +						    s->audio_num, +						    s->teletext_pid, +						    s->scrambled, +						    //FIXME: s->subtitling_pid +						    s->ac3_pid, +						    s->service_id, +						    t->network_id, +						    s->transport_stream_id, +						    t->orbital_pos, +						    t->we_flag, +						    vdr_dump_provider, +						    ca_select, +						    vdr_version, +						    vdr_dump_channum, +						    s->channel_num); +				break; +			  case OUTPUT_ZAP: +				zap_dump_service_parameter_set (stdout, +						    s->service_name, +						    t->type, +						    &t->param, +						    sat_polarisation(t), +						    sat_number(t), +						    s->video_pid, +						    s->audio_pid, +						    s->service_id); +			  default: +				break; +			  } +		} +	} +	info("Done.\n"); +} + +static void handle_sigint(int sig) +{ +	error("interrupted by SIGINT, dumping partial result...\n"); +	dump_lists(); +	exit(2); +} + +static const char *usage = "\n" +	"usage: %s [options...] [-c | initial-tuning-data-file]\n" +	"	scan doesn't do frequency scans, hence it needs initial\n" +	"	tuning data for at least one transponder/channel.\n" +	"	-c	scan on currently tuned transponder only\n" +	"	-v 	verbose (repeat for more)\n" +	"	-q 	quiet (repeat for less)\n" +	"	-a N	use DVB /dev/dvb/adapterN/\n" +	"	-f N	use DVB /dev/dvb/adapter?/frontendN\n" +	"	-d N	use DVB /dev/dvb/adapter?/demuxN\n" +	"	-s N	use DiSEqC switch position N (DVB-S only)\n" +	"	-i N	spectral inversion setting (0: off, 1: on, 2: auto [default])\n" +	"	-n	evaluate NIT-other for full network scan (slow!)\n" +	"	-5	multiply all filter timeouts by factor 5\n" +	"		for non-DVB-compliant section repitition rates\n" +	"	-o fmt	output format: 'zap' (default), 'vdr' or 'pids' (default with -c)\n" +	"	-x N	Conditional Axcess, (default 1)\n" +	"		N=0 gets only FTA channels\n" +	"		N=xxx sets ca field in vdr output to :xxx:\n" +	"	-t N	Service select, Combined bitfield parameter.\n" +	"		1 = TV, 2 = Radio, 4 = Other, (default 7)\n" +	"	-p	for vdr output format: dump provider name\n" +	"	-e N	VDR version, default 2 for VDR-1.2.x\n" +	"		ANYTHING ELSE GIVES NONZERO NIT and TID\n" +	"	-l lnb-type (DVB-S Only) (use -l help to print types) or \n" +	"	-l low[,high[,switch]] in Mhz\n" +	"	-u      UK DVB-T Freeview channel numbering for VDR\n"; + +void +bad_usage(char *pname, int prlnb) +{ +int i; +struct lnb_types_st *lnbp; +char **cp; + +	if (!prlnb) { +		fprintf (stderr, usage, pname); +	} else { +		i = 0; +		fprintf(stderr, "-l <lnb-type> or -l low[,high[,switch]] in Mhz\nwhere <lnb-type> is:\n"); +		while(NULL != (lnbp = lnb_enum(i))) { +			fprintf (stderr, "%s\n", lnbp->name); +			for (cp = lnbp->desc; *cp ; cp++) { +				fprintf (stderr, "   %s\n", *cp); +			} +			i++; +		} +	} +} + +int main (int argc, char **argv) +{ +	char frontend_devname [80]; +	int adapter = 0, frontend = 0, demux = 0; +	int opt, i; +	int frontend_fd; +	int fe_open_mode; +	const char *initial = NULL; + +	/* start with default lnb type */ +	lnb_type = *lnb_enum(0); +	while ((opt = getopt(argc, argv, "5cnpa:f:d:s:o:x:e:t:i:l:vq:u")) != -1) { +		switch (opt) { +		case 'a': +			adapter = strtoul(optarg, NULL, 0); +			break; +		case 'c': +			current_tp_only = 1; +			output_format = OUTPUT_PIDS; +			break; +		case 'n': +			get_other_nits = 1; +			break; +		case 'd': +			demux = strtoul(optarg, NULL, 0); +			break; +		case 'f': +			frontend = strtoul(optarg, NULL, 0); +			break; +		case 'p': +			vdr_dump_provider = 1; +			break; +		case 's': +			switch_pos = strtoul(optarg, NULL, 0); +			break; +		case 'o': +                        if      (strcmp(optarg, "zap") == 0) output_format = OUTPUT_ZAP; +                        else if (strcmp(optarg, "vdr") == 0) output_format = OUTPUT_VDR; +                        else if (strcmp(optarg, "pids") == 0) output_format = OUTPUT_PIDS; +                        else { +				bad_usage(argv[0], 0); +				return -1; +			} +			break; +		case '5': +			long_timeout = 1; +			break; +		case 'x': +			ca_select = strtoul(optarg, NULL, 0); +			break; +		case 'e': +			vdr_version = strtoul(optarg, NULL, 0); +			break; +		case 't': +			serv_select = strtoul(optarg, NULL, 0); +			break; +		case 'i': +			spectral_inversion = strtoul(optarg, NULL, 0); +			break; +		case 'l': +			if (lnb_decode(optarg, &lnb_type) < 0) { +				bad_usage(argv[0], 1); +				return -1; +			} +			break; +		case 'v': +			verbosity++; +			break; +		case 'q': +			if (--verbosity < 0) +				verbosity = 0; +			break; +		case 'u': +			vdr_dump_channum = 1; +			break; +		default: +			bad_usage(argv[0], 0); +			return -1; +		}; +	} + +	if (optind < argc) +		initial = argv[optind]; +	if ((!initial && !current_tp_only) || (initial && current_tp_only) || +			(spectral_inversion > 2)) { +		bad_usage(argv[0], 0); +		return -1; +	} +	lnb_type.low_val *= 1000;	/* convert to kiloherz */ +	lnb_type.high_val *= 1000;	/* convert to kiloherz */ +	lnb_type.switch_val *= 1000;	/* convert to kiloherz */ +	if (switch_pos >= 4) { +		fprintf (stderr, "switch position needs to be < 4!\n"); +		return -1; +	} +	if (initial) +		info("scanning %s\n", initial); + +	snprintf (frontend_devname, sizeof(frontend_devname), +		  "/dev/dvb/adapter%i/frontend%i", adapter, frontend); + +	snprintf (demux_devname, sizeof(demux_devname), +		  "/dev/dvb/adapter%i/demux%i", adapter, demux); +	info("using '%s' and '%s'\n", frontend_devname, demux_devname); + +	for (i = 0; i < MAX_RUNNING; i++) +		poll_fds[i].fd = -1; + +	fe_open_mode = current_tp_only ? O_RDONLY : O_RDWR; +	if ((frontend_fd = open (frontend_devname, fe_open_mode)) < 0) +		fatal("failed to open '%s': %d %m\n", frontend_devname, errno); +	/* determine FE type and caps */ +	if (ioctl(frontend_fd, FE_GET_INFO, &fe_info) == -1) +		fatal("FE_GET_INFO failed: %d %m\n", errno); + +	if ((spectral_inversion == INVERSION_AUTO ) && +	    !(fe_info.caps & FE_CAN_INVERSION_AUTO)) { +		info("Frontend can not do INVERSION_AUTO, trying INVERSION_OFF instead\n"); +		spectral_inversion = INVERSION_OFF; +	} + +	signal(SIGINT, handle_sigint); + +	if (current_tp_only) { +		current_tp = alloc_transponder(0); /* dummy */ +		/* move TP from "new" to "scanned" list */ +		list_del_init(¤t_tp->list); +		list_add_tail(¤t_tp->list, &scanned_transponders); +		current_tp->scan_done = 1; +		scan_tp (); +	} +	else +		scan_network (frontend_fd, initial); + +	close (frontend_fd); + +	dump_lists (); + +	return 0; +} + +static void dump_dvb_parameters (FILE *f, struct transponder *t) +{ +	switch (output_format) { +		case OUTPUT_PIDS: +		case OUTPUT_VDR: +			vdr_dump_dvb_parameters(f, t->type, &t->param, +					sat_polarisation (t), t->orbital_pos, t->we_flag); +			break; +		case OUTPUT_ZAP: +			zap_dump_dvb_parameters (f, t->type, &t->param, +					sat_polarisation (t), sat_number (t)); +			break; +		default: +			break; +	} +} diff --git a/util/scan/scan.h b/util/scan/scan.h new file mode 100644 index 0000000..8209076 --- /dev/null +++ b/util/scan/scan.h @@ -0,0 +1,29 @@ +#ifndef __SCAN_H__ +#define __SCAN_H__ + +#include <stdio.h> +#include <errno.h> + +extern int verbosity; + +#define dprintf(level, fmt...)			\ +	do {					\ +		if (level <= verbosity)		\ +			fprintf(stderr, fmt);	\ +	} while (0) + +#define dpprintf(level, fmt, args...) \ +	dprintf(level, "%s:%d: " fmt, __FUNCTION__, __LINE__ , ##args) + +#define fatal(fmt, args...) do { dpprintf(-1, "FATAL: " fmt , ##args); exit(1); } while(0) +#define error(msg...) dprintf(0, "ERROR: " msg) +#define errorn(msg) dprintf(0, "%s:%d: ERROR: " msg ": %d %m\n", __FUNCTION__, __LINE__, errno) +#define warning(msg...) dprintf(1, "WARNING: " msg) +#define info(msg...) dprintf(2, msg) +#define verbose(msg...) dprintf(3, msg) +#define moreverbose(msg...) dprintf(4, msg) +#define debug(msg...) dpprintf(5, msg) +#define verbosedebug(msg...) dpprintf(6, msg) + +#endif + diff --git a/util/szap/Makefile b/util/szap/Makefile new file mode 100644 index 0000000..688c5d7 --- /dev/null +++ b/util/szap/Makefile @@ -0,0 +1,35 @@ +CC = gcc +CFLAGS = -MD -Wall -g -O2 -I../../include -I../lib +LFLAGS = -Wall -g -O2 +RM = rm -f + +TARGETS = szap tzap czap femon +OBJS = szap.o tzap.o czap.o femon.o + +all: $(OBJS) $(TARGETS) +	@echo +	@echo "--------------------------------------------------------------------------------" +	@echo " please copy an appropriate channels.conf-XXX channel list for DVB-S/C/T" +	@echo +	@echo "   to ~/.szap/channels.conf" +	@echo "      ~/.czap/channels.conf" +	@echo "      ~/.tzap/channels.conf" +	@echo +	@echo " and then call ./szap for DVB-S, ./czap for DVB-C or ./tzap for DVB-T" +	@echo "--------------------------------------------------------------------------------" +	@echo + +szap: szap.o ../lib/lnb.o +	$(CC) $(LFLAGS) -o szap szap.o ../lib/lnb.o + +.c.o: +	$(CC) $(CFLAGS) -o $@ -c $< + +.o: +	$(CC) $(LFLAGS) -o $@ $< + +clean: +	$(RM) $(TARGETS) core* *.o *.d .depend + +-include $(wildcard *.d) dummy + diff --git a/util/szap/README b/util/szap/README new file mode 100644 index 0000000..5c83c67 --- /dev/null +++ b/util/szap/README @@ -0,0 +1,47 @@ +Hi, + +this are some trivial zapping applications explaining how to use the frontend +and demux API. They are also pretty useful to test your hardware. + +For DVB-S, Astra Channel config file: + +$ ./szap -c channels.conf-dvbs-astra n24 + +will tune to N24. For DVB-C, Berlin Cable channel config: + +$ ./czap -c channels.conf-dvbc-berlin Arte + +For DVB-T, Berlin Config: + +$ ./czap -c channels.conf-dvbt-berlin phoenix + +By default the MPEG stream is routed to a hardware decoder. If you want to  +record the stream to disk you will route it to the DVR device by using the  +'-r' option: + +$ ./czap -c channels.conf-dvbt-berlin phoenix -r +[keep it running in one console] +$ cat /dev/dvr/adapter0/dvr0 > /tmp/recording.ts +[in a second console, will dump the MPEG transport stream to /tmp/recording.ts] + +The status messages have the following meaning: + +status 0x1f              --- The demodulator status bits. +			      0x1f means all bits set, everything ok. + +signal [0x0000...0xffff] --- Signal Strength. Values above 0x8000 should be ok. + +snr [0x0000...0xffff]    --- Signal/Noise Ratio. Values above 0x8000 are ok. + +ber [0...0xffffffff]     --- Bit Error Rate. The less the better. + +unc [0...0xffffffff]     --- Number of Uncorrectable Blocks. +			     Small numbers are Preferable. + +If everything is alright and all frontend circuits are working stable  +(are locked) you should see a FE_HAS_LOCK in the rightmost line. + +Good luck, + +Holger + diff --git a/util/szap/channels.conf-dvbc-berlin b/util/szap/channels.conf-dvbc-berlin new file mode 100644 index 0000000..7fb05a5 --- /dev/null +++ b/util/szap/channels.conf-dvbc-berlin @@ -0,0 +1,171 @@ +3sat:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:210:220 +ARD-Online-Kanal:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1805 +CNBC:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:510:520 +DLF-Köln:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:810 +DLR-Berlin:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:710 +EinsExtra:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:101:102 +EinsFestival:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:201:202 +EinsMuXx:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:301:302 +EuroNews:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2221:2233 +Eurosport:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:410:420 +Fritz:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:901 +KiKa:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:310:320 +MDR FERNSEHEN:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:401:402 +MDR KULTUR:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:801 +MDR info:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1101 +MHP ARD Online-Kanal:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:102 +NDR Fernsehen:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2401:2402 +ORB-Fernsehen:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:501:502 +RADIOmultikulti:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1301 +Radio 3:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:701 +SFB1:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:601:602 +SWR2:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1401 +SÜDWEST BW:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:801:802 +SÜDWEST RP:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3101:3102 +WDR 3:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1501 +WDR 5:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1601 +ZDF:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:110:120 +ZDFdigitext:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +ZDFdokukanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:660:670 +ZDFinfokanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:610:620 +ZDFtheaterkanal:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +JUMP:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1001 +SPUTNIK:426000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:1201 +Österreich 1:394000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:169 +ATV 2:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:631:632 +ATV 2:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:631:632 +Adagio:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +All Jazz:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Avante:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:741:743 +B5 aktuell:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3101 +BBC Prime:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:761:762 +BData3:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +BData4:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +BData5:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +BR-alpha:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:701:702 +Barock Fantasie:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Bayerisches FS:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:201:202 +Bayern 1:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3601 +Bayern 4 Klassik:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3001 +BibelTV:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:731:732 +Bloomberg:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +CLASSICA:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:767:768 +COUNTRY:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:656 +Canal 24 Horas:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:991:992 +Club:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:711:713 +Cristal New Age:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +DANCE:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:304 +DW-tv:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:634:632 +Das Erste:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:101:102 +Detskij Mir:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:931:932 +ERT-Sat:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:691:692 +Einstein TV:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:701:702 +Euronews:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:597:596 +Eurosport News:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:771:772 +Extreme Sports:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:791:793 +Extreme Sports:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Fashion TV:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Fox Kids:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:671:672 +Fox Kids:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:671:673 +GOLD:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:320 +HITLISTE:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:784 +HR XXL:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3501 +JAZZ:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:640 +Jazz legends:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Kabel Wizard:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Kanal 7:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Kanal 7:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:49:52 +Kanal D:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:651:652 +Kanal D:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:651:652 +LATIN:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:368 +Landscape:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Leitseite:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2254:0 +Liberty TV:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:721:723 +MTV Base:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:781:782 +MV-Test:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Modem-Setup:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Movie Sounds:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Musica Antica:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +Musica Camerata:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +NDR Info:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3701 +NTV international:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +NTVI:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:611:612 +Nashe Kino:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:621:622 +NordwestRadio:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3801 +OLD GOLD:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:336 +Opernfestival:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +PCNE:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:681:682 +PREMIERE SPORT INTERACTIVE:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +PREMIERE DIREKT 1:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +PREMIERE DIREKT 2:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +PREMIERE DIREKT 3:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +PREMIERE DIREKT 4:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2815:2816 +PREMIERE EROTIK:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1279:1280 +PREMIERE NOSTALGIE:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2559:2560 +PREMIERE SERIE:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1023:1024 +PREMIERE SPORT 1:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:258 +PREMIERE SPORT 2:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3839:3840 +PREMIERE START:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:256 +Parlamentsfernsehen:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:33:36 +Phoenix:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:901:902 +Portal:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +RTP Internacional:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:661:662 +Rai 1:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:951:952 +Rai 2:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:961:962 +Rai 3:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:971:972 +SCHLAGER:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:384 +SR 1:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3901 +SR Fernsehen Suedwest:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:501:502 +Show TV:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:911:912 +Sinfonica:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +TGRT:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:921:922 +TM V1.0:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +TV Polonia:434000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:641:642 +TVEi:121000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:981:982 +TW1:113000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:751:752 +Test-R:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:701:702 +Travel:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:595:594 +VCR-Setup:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +VH1 Classic:610000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:604:603 +Videotext:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +WDR FERNSEHEN:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:601:602 +ZEE TV:442000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +arte:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:401:403 +hessen fernsehen:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:301:302 +hr-chronos:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3201 +hr-klassik:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3401 +hr2:410000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:3301 +13 TH STREET:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2303:2304 +ALTERNATIVE ROCK:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:544 +BEATE-UHSE.TV:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1023:1024 +CHILLOUT:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:400 +CLASSIC ROCK:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:352 +DISCOVERY CHANNEL:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1791:1792 +DISNEY CHANNEL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2559:2560 +DEUTSCHE HITS:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:800 +EASY LISTENING:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:608 +Einstein:346000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +FILM & MUSICAL:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:592 +FOX KIDS:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1279:1280 +GOLDSTAR TV:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:3839:3840 +HARD ROCK:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:816 +HEIMATKANAL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536 +HIP HOP/R&B:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:576 +JUNIOR:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:255:256 +K-TOON:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 +KLASSIK POPULÄR:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:624 +KRIMI &CO:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536 +LOVE SONGS:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:592 +NEW COUNTRY:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:384 +ORCHESTRALE WERKE:378000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:560 +PLANET:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1791:1792 +PREMIERE 1:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:511:512 +PREMIERE 2:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1791:1793 +PREMIERE 3:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2303:2304 +PREMIERE 4:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:767:768 +PREMIERE 5:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1279:1280 +PREMIERE 6:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1535:1536 +PREMIERE 7:370000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:1023:1024 +SOUL CLASSICS:362000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:352 +STUDIO UNIVERSAL:354000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:2047:2048 +Sonnenklar TV:402000000:INVERSION_OFF:6900000:FEC_NONE:QAM_64:0:0 diff --git a/util/szap/channels.conf-dvbs-astra b/util/szap/channels.conf-dvbs-astra new file mode 100644 index 0000000..705f710 --- /dev/null +++ b/util/szap/channels.conf-dvbs-astra @@ -0,0 +1,226 @@ +Das Erste:11837:h:0:27500:101:102:1:28106 +ZDF:11954:h:0:27500:110:120:1:28006 +3sat:11954:h:0:27500:210:220:1:28007 +EinsMuXx:12110:h:0:27500:301:302:1:28203 +EinsFestival:12110:h:0:27500:201:202:1:28202 +EinsExtra:12110:h:0:27500:101:102:1:28201 +MDR FERNSEHEN:12110:h:0:27500:401:402:1:28204 +ORB-Fernsehen:12110:h:0:27500:501:502:1:28205 +B1 Berlin:12110:h:0:27500:601:602:1:28206 +SWR Fernsehen:11837:h:0:27500:801:802:1:28113 +SR Fernsehen Suedwes:11837:h:0:27500:501:502:1:28110 +hessen fernsehen:11837:h:0:27500:301:302:1:28108 +WDR FERNSEHEN:11837:h:0:27500:601:602:1:28111 +Bayerisches FS:11837:h:0:27500:201:202:1:28107 +N3:12110:h:0:27500:2401:2402:1:28224 +BR-alpha:11837:h:0:27500:701:702:1:28112 +KiKa:11954:h:0:27500:310:320:1:28008 +arte:11836:h:0:27500:401:402:1:28109 +ZDF Theaterkanal:11954:h:0:27500:1110:1120:1:28016 +ZDF.info:11954:h:0:27500:610:620:1:28011 +ZDF.doku:11954:h:0:27500:660:670:1:28014 +Phoenix:11837:h:0:27500:901:902:1:28114 +DW-tv:10786:v:0:21997:305:306:1:9005 +RTL Television:12188:h:0:27500:163:104:1:12003 +SAT.1:12480:v:0:27500:1791:1792:1:46 +ProSieben:12480:v:0:27500:255:256:1:898 +RTL2:12188:h:0:27500:166:128:1:12020 +Super RTL:12188:h:0:27500:165:120:1:12040 +KABEL1:12480:v:0:27500:511:512:1:899 +VOX:12188:h:0:27500:167:136:1:12060 +tm3:12480:v:0:27500:767:768:1:897 +Bloomberg TV Germany:12552:v:0:22000:162:99:1:12160 +EuroNews:11954:h:0:27500:2221:2233:1:28015 +N24:12480:v:0:27500:2047:2048:1:47 +n-tv:12670:v:0:22000:162:96:1:12730 +DSF:12480:v:0:27500:1023:1024:1:900 +Eurosport:11954:h:0:27500:410:420:1:28009 +Via 1 - Sch ner Re:12148:h:0:27500:511:512:1:44 +Home Order Tel:12480:v:0:27500:1279:1280:1:40 +QVC GERMANY:12552:v:0:22000:165:166:1:12100 +TW 1:12692:h:0:22000:166:167:1:13013 +Canal Canarias:12441:v:0:27500:513:681:1:29700 +ProSieben A:12051:v:0:27500:161:84:1:20002 +ProSieben CH:12051:v:0:27500:289:290:1:20001 +Kabel 1 Austria:12051:v:0:27500:166:167:1:20004 +Kabel 1 Schweiz:12051:v:0:27500:162:163:1:20003 +CNN Int.:12168:v:0:27500:165:100:1:28512 +Sky News:12552:v:0:22000:305:306:1:3995 +Travel:12168:v:0:27500:163:92:1:28001 +AB SAT / XXL:12266:h:0:27500:164:96:1:17004 +MOTEURS:12266:h:0:27500:160:80:1:17000 +HOT GM:12148:h:0:27500:767:768:1:45 +KTO:12129:v:0:27500:170:120:1:8411 +LA CINQUIEME:12207:v:0:27500:160:80:1:8501 +LCP:12207:v:0:27500:165:100:1:8506 +LibertyTV.com:12611:v:0:22000:941:942:1:12280 +TV5 Europe:12611:v:0:22000:45:46:1:12240 +Motors TV:12611:v:0:22000:191:194:1:12300 +Wishline:12611:v:0:22000:214:216:1:12320 +TV 5:10786:v:0:21997:164:112:1:9001 +RTM - MAROC:10786:v:0:21997:162:96:1:9002 +ESC1 - EGYPTE:10786:v:0:21997:163:104:1:9003 +RAI 1:10786:v:0:21997:289:290:1:9004 +RTPI:10786:v:0:21997:300:301:1:9006 +TV7:10786:v:0:21997:166:128:1:9007 +ARTE:10786:v:0:21997:167:136:1:9009 +Colourbars:12611:v:0:22000:48:49:1:3982 +Alice:12611:v:0:22000:162:96:1:12200 +Video Italia:12611:v:0:22000:121:122:1:12220 +ANDALUCIA TV:11934:v:0:27500:166:104:1:29011 +TVC INT.:12441:v:0:27500:512:660:1:29701 +TV4:11992:h:0:27500:165:98:1:20365 +TV Niepokalanow:11876:h:0:27500:161:82:1:20601 +VIVA:12670:v:0:22000:309:310:1:12732 +VIVA ZWEI:12552:v:0:22000:171:172:1:12120 +MTV Central:12699:v:0:22000:3031:3032:1:28643 +ONYX:12692:h:1:27500:161:84:1:502 +VIVA polska:11603:h:1:27500:190:191:1:611 +DeeJay TV:11603:h:1:27500:160:161:1:602 +NBC:11053:h:1:27500:550:551:1:8008 +EWTN:10722:h:1:29900:1001:1201:1:4601 +MTA INTL:10722:h:1:29900:1004:1204:1:4604 +VOX:11053:h:1:27500:500:501:1:8002 +SAT.1 A:11053:h:1:27500:511:512:1:8003 +RTL2 AUSTRIA:11053:h:1:27500:520:521:1:8004 +ZDF:11053:h:1:27500:570:571:1:8011 +K-TV:11053:h:1:27500:580:581:1:8012 +RTL Television:11053:h:1:27500:160:80:1:8001 +ARTE:11059:v:1:6510:98:99:1:1 +HOT Italia:11095:h:1:27500:4194:4195:1:3714 +Olisat:11095:h:1:27500:33:34:1:3718 +VIVA-POLSKA:11128:h:1:4340:98:99:1:1 +DW-tv:11195:v:1:9099:101:102:1:5301 +Canal 24 Horas:11203:h:1:3999:4130:4131:1:5301 +TV5:11337:v:1:5631:512:640:1:1 +SAT.1 CH:11603:h:1:27500:101:102:1:601 +KurdSat:11603:h:1:27500:111:112:1:603 +ARD "Das Erste":11603:h:1:27500:172:173:1:606 +RTL 2 CH:11603:h:1:27500:175:176:1:609 +Super RTL A:11603:h:1:27500:180:181:1:610 +TV ROMANIA:11622:v:1:27500:227:247:1:10707 +MRTV:11622:v:1:27500:222:242:1:10702 +102.5 HIT Ch:11622:v:1:27500:224:244:1:10704 +TLC SAT:11622:v:1:27500:225:245:1:10705 +PRO-SAT:11622:v:1:27500:246:226:1:10706 +Channel SUN:11622:v:1:27500:229:249:1:10709 +Racing Channel:11622:v:1:27500:228:248:1:10708 +3 ABN:11622:v:1:27500:221:241:1:10701 +Bloom.Germany:11642:h:1:27500:1460:1420:1:4 +Bloomberg TV UK:11642:h:1:27500:1560:1520:1:4 +Sat 7:11642:h:1:27500:1660:1620:1:4 +EDTV 1:11746:h:1:27500:4130:4131:1:9501 +EDTV SPORT:11746:h:1:27500:4386:4387:1:9502 +EDTV BUSINESS:11746:h:1:27500:4642:4643:1:9503 +EDTV DRAMA:11746:h:1:27500:4898:4899:1:9504 +RAI1:11765:v:1:27499:160:80:1:3401 +RAI2:11765:v:1:27499:161:84:1:3402 +RAI3:11765:v:1:27499:162:88:1:3403 +RaiWayTEST2:11765:v:1:27499:516:654:1:3405 +RAIMOSAICO:11765:v:1:27499:518:8191:1:3407 +RAINews24:11803:v:1:27500:516:654:1:3301 +CAMERA DEPUTATI:11803:v:1:27500:517:655:1:3302 +TELEPACE:11803:v:1:27500:515:653:1:3304 +RAISPORTSAT:11803:v:1:27500:512:650:1:3305 +RAINettunoSAT2:11803:v:1:27500:513:651:1:3306 +RAIeducational:11803:v:1:27500:514:652:1:3307 +RAINettunoSAT1:11803:v:1:27500:519:657:1:3308 +SAT2000:11803:v:1:27500:518:656:1:3309 +I1:11918:v:1:27499:512:650:1:1 +C5:11918:v:1:27499:513:660:1:2 +R4:11918:v:1:27499:514:670:1:3 +Telesierra:12091:h:1:27500:4160:4161:1:8704 +C. Milagro:12091:h:1:27500:4368:4369:1:8711 +Italia Sat:12091:h:1:27500:4600:4601:1:8728 +TVE Internacional:12091:h:1:27500:4208:4209:1:8707 +Fiesta:12091:h:1:27500:4432:4433:1:8720 +Retelsat:12091:h:1:27500:4464:4465:1:8722 +ART EUROPE:12013:h:1:27495:164:96:1:450 +EGYPT SAT. CH. 2:12013:h:1:27495:166:104:1:470 +IQRA:12013:h:1:27495:168:112:1:474 +MAURITANIA TV:12110:v:1:27500:230:231:1:704 +ARMENIA TV:12110:v:1:27500:240:241:1:705 +SAILING CHANNEL:12110:v:1:27500:260:261:1:707 +AL JAZEERA:12110:v:1:27500:270:271:1:708 +Coming Soon TV:12110:v:1:27500:310:311:1:717 +SaluteBenessere:12110:v:1:27500:320:321:1:718 +AH-EDP1:12148:v:1:27499:96:97:1:7201 +AH-EDP2:12148:v:1:27499:112:113:1:7202 +Espresso:12148:v:1:27499:192:193:1:7203 +Alice:12148:v:1:27499:160:161:1:7220 +Nuvolari:12148:v:1:27499:176:177:1:7221 +Leonardo:12148:v:1:27499:128:129:1:7222 +AH-EDP3:12148:v:1:27499:36:37:1:7205 +OTE Promo:12187:v:1:27500:517:655:1:1001 +RTS SAT:12187:v:1:27500:519:657:1:1022 +ERT SAT:12187:v:1:27500:514:652:1:1102 +EXTRA:12187:v:1:27500:516:654:1:1106 +TRIAL:12187:v:1:27500:513:651:1:1108 +Minimax:11303:h:1:19540:300:301:1:3 +TVN1:12209:h:1:5631:4194:4195:1:1 +RR TEST:10978:v:1:8998:33:34:1:1 +TV 5 Thailand:10978:v:1:8998:1057:1058:1:2 +TEST-1:10978:v:1:8998:3105:3106:1:4 +FASHION:12244:h:1:27500:123:133:1:103 +AJARA TV:12244:h:1:27500:127:137:1:107 +SLO-TV1:12300:v:1:27495:200:201:1:3201 +POLONIA 1:12302:v:1:27500:205:206:1:3203 +SUPER 1:12302:v:1:27500:207:208:1:3207 +NAPOLI INT.:12302:v:1:27500:240:241:1:3210 +MAGIC:12302:v:1:27500:245:246:1:3211 +COUNTDOWN:12302:v:1:27500:235:236:1:3212 +TBNE:12302:v:1:27500:230:231:1:3213 +NAPOLI CHANNEL:12302:v:1:27500:227:228:1:3215 +KURDISTAN TV:12302:v:1:27500:225:226:1:3214 +ATLAS TV:12379:v:1:27500:3022:3032:1:3002 +TELE 24 SWITZERLAND:12379:v:1:27500:3023:3033:1:3003 +Abu Dhabi TV:12379:v:1:27500:3024:3034:1:3004 +RTV MONTENEGRO:12379:v:1:27500:3026:3036:1:3006 +JAAM-E-JAM 1:12436:h:1:27500:160:80:1:1 +JAAM-E-JAM 2:12436:h:1:27500:161:82:1:2 +SAHAR:12436:h:1:27500:162:84:1:3 +SAHAR 2:12436:h:1:27500:163:86:1:4 +IRINN:12436:h:1:27500:164:88:1:5 +Musicmax:11303:h:1:19540:500:501:1:6 +TEST:12474:h:1:27500:771:8191:1:10608 +EbS:12474:h:1:27500:101:201:1:10601 +MOU.2:12474:h:1:27500:42:43:1:10602 +PINK PLUS:12474:h:1:27500:308:256:1:10605 +LibertyTV.com:12474:h:1:27500:941:942:1:10603 +2M Maroc:12474:h:1:27500:601:602:1:10607 +ZEE TV:12474:h:1:27500:910:911:1:10604 +WorldNet Europe:12483:v:1:8299:4260:4220:1:1 +WorldNet:12483:v:1:8299:4560:4520:1:4 +SICILIA INTERNATIONA:12519:v:1:27499:501:502:1:8309 +SARDEGNA UNO:12519:v:1:27499:503:504:1:8310 +EuroMed:12519:v:1:27499:510:511:1:8312 +TGRT:12519:v:1:27499:505:506:1:8313 +VIDEOLINA:12519:v:1:27499:515:516:1:8318 +MEDIOLANUM:12538:h:1:27500:1131:1132:1:8987 +www.travel:12538:h:1:27500:1180:1183:1:8992 +MonteCarloSat:12538:h:1:27500:5126:5122:1:8877 +Bulgaria TV:12538:h:1:27500:4612:4613:1:8827 +TVN1:12571:h:1:5631:4194:4195:1:1 +JSTV 1:12595:v:1:27500:2000:2001:1:8213 +JSTV 2:12595:v:1:27500:2011:2013:1:8214 +MBC:12595:v:1:27500:160:80:1:8201 +ANN:12595:v:1:27500:161:84:1:8202 +BET:12595:v:1:27500:167:108:1:8208 +EuroNews:12595:v:1:27500:2221:2231:1:8211 +Sharjah        Arabs:12653:h:1:27500:1160:1120:1:1 +Qatar          Arabs:12653:h:1:27500:1260:1220:1:2 +Saudi 1        Arabs:12653:h:1:27500:1360:1320:1:3 +Kuwait         Arabs:12653:h:1:27500:1460:1420:1:4 +Libya          Arabs:12653:h:1:27500:1560:1520:1:5 +Sudan          Arabs:12653:h:1:27500:1660:1620:1:6 +Oman           Arabs:12653:h:1:27500:1760:1720:1:7 +Jordan         Arabs:12653:h:1:27500:1860:1820:1:8 +IRAQ TV:12653:h:1:27500:1960:1920:1:9 +Dubai Sport:12653:h:1:27500:1060:1020:1:10 +Digitaly:12672:v:1:27500:220:221:1:4203 +Telemarket:12672:v:1:27500:350:351:1:4211 +eVision:12672:v:1:27500:360:361:1:4214 +Thai TV5:12672:v:1:27500:200:201:1:4201 +Studio Europa:12672:v:1:27500:230:231:1:4204 +Video  Italia:12672:v:1:27500:340:341:1:4210 +GAME NETWORK:12672:v:1:27500:291:292:1:4213 diff --git a/util/szap/channels.conf-dvbt-australia b/util/szap/channels.conf-dvbt-australia new file mode 100644 index 0000000..9709b0b --- /dev/null +++ b/util/szap/channels.conf-dvbt-australia @@ -0,0 +1,31 @@ +ABC HDTV:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:2307:0:560 +ABC TV Melbourne:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:561 +ABC TV 2:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:562 +ABC TV 3:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:563 +ABC TV 4:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:564 +ABC DiG Radio:226500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_3_4:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:0:2311:566 +TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1585 +TEN Digital 1:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1586 +TEN Digital 2:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1587 +TEN Digital 3:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1588 +TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1589 +TEN Digital 4:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1590 +TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1591 +TEN HD:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:0:1592 +TEN Digital:219500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:650:1593 +Nine Digital:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:513:660:1072 +Nine Digital HD:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:512:0:1073 +Nine Guide:191625000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_16:HIERARCHY_NONE:514:670:1074 +7 Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1328 +7 Digital 1:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1329 +7 Digital 2:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1330 +7 Digital 3:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:769:770:1331 +7 HD Digital:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:833:834:1332 +7 Program Guide:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:865:866:1334 +SBS HD:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:102:103:784 +SBS DIGITAL 1:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:81:785 +SBS DIGITAL 2:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:162:83:786 +SBS EPG:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:163:85:787 +SBS RADIO 1:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:201:798 +SBS RADIO 2:536500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:202:799 + diff --git a/util/szap/channels.conf-dvbt-berlin b/util/szap/channels.conf-dvbt-berlin new file mode 100644 index 0000000..dbddca5 --- /dev/null +++ b/util/szap/channels.conf-dvbt-berlin @@ -0,0 +1,51 @@ +c5:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82 +c7:191500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82 +c25:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82 +c27:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82 +c33:570000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82 +c44:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82 +c56:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82 +c59:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:82 + +SWR BW:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:257:258:16 +WDR:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:241:242:15 +BBC World:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:49:50:16387 +FAB:177500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_3_4:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:3073:3074:16576 + +MDR Fernsehen:191500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:101:102:1 +arte:191500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:201:202:2 +NDR Fernsehen:191500000:INVERSION_OFF:BANDWIDTH_7_MHZ:FEC_2_3:FEC_NONE:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:301:302:3 + +RTL:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:337:338:16405 +RTL2:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:353:354:16406 +Super RTL:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:433:434:16411 +VOX:506000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:545:546:16418 + +Das Erste:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1401:1402:14 +Phoenix:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1301:1302:13 +RBB Berlin:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1201:1202:12 +RBB Brandenburg:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:1101:1102:11 + +ZDF:570000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:545:546:514 +Info/3sat:570000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:561:562:515 +Doku/KiKa:570000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:593:594:517 + +Kabel 1:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:161:162:16394 +N24:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:225:226:16398 +ProSieben:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:305:306:16403 +SAT.1:658000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:385:386:16408 + +DSF:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:129:130:16392 +Testkanal n-tv:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:273:274:16401 +VIVA Plus:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:529:530:16417 +Eurosport:754000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:577:578:16420 + +Testkanal Eurosport:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:577:578:16420 +SUD:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16642 +HUMAX DOWNLOAD SVC:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16645 +IP Services:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16640 +Media Broadcast Services:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16641 +SUD 1:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16643 +Kathrein Download:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:0:0:16644 +Testkanal MTV:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:193:194:16396 +Testkanal n-tv:778000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_16:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_8:HIERARCHY_NONE:273:274:16401 diff --git a/util/szap/channels.conf-dvbt-collserola b/util/szap/channels.conf-dvbt-collserola new file mode 100644 index 0000000..63456b2 --- /dev/null +++ b/util/szap/channels.conf-dvbt-collserola @@ -0,0 +1,25 @@ +#channels.conf for DVB-T - Collserola (Barcelona) Transmitter + +#C43 +TV3:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:111:112:801 +K3/33:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:121:122:802 +3/24:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:131:132:803 +Canal Pilot:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:141:142:804 +3XL.net:650000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_2_3:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:151:152:805 + +#C61 +TVE 1:794000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:101:103:1377 +TVE 2:794000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:201:203:1441 +ANTENA 3:794000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:303:1121 +CANAL+:794000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:501:503:1057 +TELECINCO:794000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:403:1185 + +#C66 +Veo TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:302:1536 +Net TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:402:1825 +Video Promocional 1:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:210:212:425 +Video Promocional 2:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:110:0:420 +[1388]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5000 +[138c]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5004 +[138a]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5002 + diff --git a/util/szap/channels.conf-dvbt-crystal-palace b/util/szap/channels.conf-dvbt-crystal-palace new file mode 100644 index 0000000..28fa018 --- /dev/null +++ b/util/szap/channels.conf-dvbt-crystal-palace @@ -0,0 +1,70 @@ +#channels.conf for DVB-T - Crystal Palace Transmitter + +# Multiplex 1 BBC - Channel 25, Offset -, Freq 505833333 +BBCi:505833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0:4479 +CBBC Channel:505833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0:4671 +BBC ONE:505833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:600:601 +BBC TWO:505833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:610:611 +BBC THREE:505833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:620:621 +BBC NEWS 24:505833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:640:641 + +# Multiplex 2 Digital 3&4 - Channel 22, Offset -, Freq 481833333 +Teletext:481833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +FourText:481833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +CHANNEL4:481833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2827:2828 +ITV NEWS:481833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2850:2851 +ITV 1:481833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:512:650 +ITV 2:481833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2818:2819 +Ch 14:481833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2840:2841 + +#Multiplex A SDN - Channel 32, Offset -, Frequency 561833333 +ntl:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +Ch 15:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:660 +BBC Radio 1:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:6210 +BBC Radio 2:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:6226 +BBC Radio 3:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:6242 +BBC Radio 4:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:6258 +QVC:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6049:6050 +FIVE:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6017:6018 +bid-up.tv:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6273:6274 +TV Travel Shop:561833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6161:6161 + +#Multiplex B BBC - Channel 28, Offset -, Frequency 529833333 +#Community                (0x4e00) 01: PCR 0x1fff +#703                      (0x4c80) 01: PCR 0x1fff +BBC PARLMNT:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:403 +BBC FOUR:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:401 +701:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:204:411 +702:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:203:407 +CBeebies:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:401:402 +BBC Asian Net:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:435 +1Xtra BBC:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:434 +BBC 7:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:433 +BBC 6 Music:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:432 +BBC 5L SportsX:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:431 +BBC R5 Live:529833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:430 + +# Multiplex C Crown Castle - Channel 34, Offset +, Frequency 578166666 +UKHistory:578166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:401:402 +Sky Travel:578166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:301:302 +Sky Spts News:578166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:202 +Sky News:578166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:101:102 + +# Multiplex D Crown Castle - Channel 29, Offset -, Freq 537833333 +#UKBrightIdeas            (0x64c0) 01: PCR 0x1fff +THE HITS:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:101:102 +TMF:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:202 +CBM:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:501:502 +Free2Play:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +Q:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1901 +Magic:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1801 +The Hits Radio:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1701 +BBC World Sv:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1601 +oneworld:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1501 +jazz fm:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1401 +Kerrang:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1301 +Smash Hits:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1201 +Kiss:537833333:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1101 + + + diff --git a/util/szap/channels.conf-dvbt-hannington b/util/szap/channels.conf-dvbt-hannington new file mode 100644 index 0000000..b83620e --- /dev/null +++ b/util/szap/channels.conf-dvbt-hannington @@ -0,0 +1,28 @@ +BBC One:706000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:600:601 +BBC Two:706000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:610:611 +CBBC:706000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:620:621 +BBC Three:706000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:620:621 +BBC News 24:706000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:640:641 +CBeebies:674166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:401 +BBC Four:674166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:401 +BBC Parliament:674166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:403 +701:674166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:203:407 +702:674166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:204:411 +703:674166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +ITV 1:650166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:513:651 +ITV 2:650166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2818:2819 +Channel 4:650166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2822:2823 +ITV News:650166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2822:2823 +price-drop.tv:650166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2840:2841 +Five:626166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6017:6018 +QVC:626166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6059:6050 +Tv Travel Shop:626166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6161:6162 +Channel 15:626166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:660 +bid-up.tv:626166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6273:6274 +Sky News:658166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:101:102 +Sky Sports News:658166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:202 +Sky Travel:658166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:301:302 +UK History:658166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:401:402 +The Hits:634166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:101:102 +TMF:634166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:202 +UK Bright Ideas:634166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 diff --git a/util/szap/channels.conf-dvbt-madrid b/util/szap/channels.conf-dvbt-madrid new file mode 100644 index 0000000..cdf515b --- /dev/null +++ b/util/szap/channels.conf-dvbt-madrid @@ -0,0 +1,16 @@ +Veo TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:302:1536 +Net TV:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:402:1825 +[1388]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5000 +[138c]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5004 +[138a]:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:5002 +Video Promocional:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:420 +Informe Semanal:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:0:0:425 +TVE 2:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:201:203:1441 +ANTENA 3:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:301:303:1121 +TELECINCO:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:401:403:1185 +CANAL+:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:501:503:1057 +TVE 1:770000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:101:103:1377 +Telemadrid:810000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:111:113:421 +La Otra:810000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:211:212:422 +Quiero Madrid:810000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:411:412:424 +Onda 6:810000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_1_2:QAM_64:TRANSMISSION_MODE_8K:GUARD_INTERVAL_1_4:HIERARCHY_NONE:311:312:423 diff --git a/util/szap/channels.conf-dvbt-oxford b/util/szap/channels.conf-dvbt-oxford new file mode 100644 index 0000000..29a53a2 --- /dev/null +++ b/util/szap/channels.conf-dvbt-oxford @@ -0,0 +1,41 @@ +BBC-Choice:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:620:621 +BBC-Knowledge:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:630:631 +BBC-News24:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:640:641 +BBC-1:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:600:601 +BBC-Parliament:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:660 +BBC-2:578000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:610:611 +ITV-1:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:513:651 +ITV-2:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2818:2819 +ITV-Sport:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2836:2837 +FilmFour:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2822:2823 +C4:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2826:2827 +E4:850000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2831:2832 +C5:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6017:6018 +Shop:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6049:6050 +ITVSelect-Info:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6065:6066 +ITVSelect-1:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6081:6082 +ITVSelect-2:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6097:6098 +ITVSelect-3:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6113:6114 +ITVSelect-4:713833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6129:6130 +Carlton-Cinema:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:288:289 +Sky-One:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:544:545 +Sky-Sports-1:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:800:801 +Sky-Premier:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1056:1057 +CartoonNetwork:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1312:1313 +UK-Horizons:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2336:2337 +ITV-Sport-Plus:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2592:2593 +ITVSportSelect:721833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:2596 +BreezeMen&Mtrs:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:800:801 +Granada-Plus:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:544:545 +MTV:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1568:1569 +Sky-Movie-Max:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1312:1313 +Sky-Sports-2:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2080:2081 +UK-Gold:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:288:289 +Wellbeing:690000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1824:1825 +PLAY-uk:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:288:289 +UK-Style:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:544:545 +no-name:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:800:801 +Discovery:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:1312:1313 +Nick/Paramount:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2080:2081 +Sky-Sports-3:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2336:2337 +Brit-Eurosport:538000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2592:2593 diff --git a/util/szap/channels.conf-dvbt-reigate b/util/szap/channels.conf-dvbt-reigate new file mode 100644 index 0000000..f5fe7cc --- /dev/null +++ b/util/szap/channels.conf-dvbt-reigate @@ -0,0 +1,51 @@ +BBC ONE:554000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:600:601 +BBC TWO:554000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:610:611 +ITV 1:474000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:512:650 +Channel 4:474000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2827:2828 +five:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6017:6018 +ITV 2:474000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2818:2819 +BBC THREE:554000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +Teletext:474000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +BBC FOUR:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +Sky Travel:618166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:301:302 +UKHistory:618166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:401:402 +Ch 14:474000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2840:2841 +Ch 15:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:660 +QVC:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6049:6050 +TV Travel Shop:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6161:6162 +The HITS:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:101:102 +UKBrightIdeas:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:301:302 +f tn:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +TMF:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:202 +bid-up.tv:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6273:6274 +CBM:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:501:502 +CBBC Channel:554000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:620:621 +CBeebies:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:401 +BBC NEWS 24:554000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:640:641 +ITV News:474000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2850:2851 +Sky News:618166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:101:102 +Sky Spts News:618166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:201:202 +BBC PARLMNT:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:403 +Community:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +FourText:474000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +BBCi:554000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +ntl:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 +BBC Radio 1:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:6210 +1Xtra BBC:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:434 +BBC Radio 2:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:6226 +BBC Radio 3:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:6242 +BBC Radio 4:498000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_1_2:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:6258 +BBC R5 Live:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:430 +BBC 5L SportsX:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:431 +BBC 6 Music:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:432 +BBC 7:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:433 +BBC Asian Net.:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:435 +BBC World Sv.:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1601 +Smash Hits!:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1201 +Kiss:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1101 +Kerrang!:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1301 +jazz fm:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1401 +oneword:834000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:1501 +701:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:203:407 +702:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:204:411 +703:522000000:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_3_4:FEC_NONE:QAM_16:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:0 diff --git a/util/szap/channels.conf-dvbt-sandy_heath b/util/szap/channels.conf-dvbt-sandy_heath new file mode 100644 index 0000000..a0cc632 --- /dev/null +++ b/util/szap/channels.conf-dvbt-sandy_heath @@ -0,0 +1,13 @@ +BBC-Choice:641833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:620:621 +BBC-Knowledge:641833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:630:631 +BBC-News24:641833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:640:641 +BBC-1:641833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:600:601 +BBC-Parliament:641833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:0:660 +BBC-2:641833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:610:611 +ITV-1:665833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:513:651 +ITV-2:665833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2819:2820 +C4:665833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2823:2824 +E4:665833334:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:2831:2832 +C5:650166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6017:6018 +Shop:650166666:INVERSION_OFF:BANDWIDTH_8_MHZ:FEC_2_3:FEC_NONE:QAM_64:TRANSMISSION_MODE_2K:GUARD_INTERVAL_1_32:HIERARCHY_NONE:6049:6050 + diff --git a/util/szap/czap.c b/util/szap/czap.c new file mode 100644 index 0000000..9d183f9 --- /dev/null +++ b/util/szap/czap.c @@ -0,0 +1,368 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <fcntl.h> +#include <ctype.h> +#include <errno.h> + +#include <linux/dvb/frontend.h> +#include <linux/dvb/dmx.h> + + +static char FRONTEND_DEV [80]; +static char DEMUX_DEV [80]; + +#define CHANNEL_FILE "/.czap/channels.conf" + +#define ERROR(x...)							\ +	do {								\ +		fprintf(stderr, "ERROR: ");				\ +		fprintf(stderr, x);					\ +		fprintf (stderr, "\n");					\ +	} while (0) + +#define PERROR(x...)							\ +	do {								\ +		fprintf(stderr, "ERROR: ");				\ +		fprintf(stderr, x);					\ +		fprintf (stderr, " (%s)\n", strerror(errno));		\ +	} while (0) + + +typedef struct { +	char *name; +	int value; +} Param; + +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 } +}; + +#define LIST_SIZE(x) sizeof(x)/sizeof(Param) + + +static +int parse_param(const char *val, const Param * plist, int list_size) +{ +	int i; + +	for (i = 0; i < list_size; i++) { +		if (strcasecmp(plist[i].name, val) == 0) +			return plist[i].value; +	} +	return -1; +} + + +static char line_buf[256]; +static +char *find_channel(FILE *f, int list_channels, int *chan_no, const char *channel) +{ +	size_t l; +	int lno = 0; + +	l = channel ? strlen(channel) : 0; +	while (!feof(f)) { +		if (!fgets(line_buf, sizeof(line_buf), f)) +			return NULL; +		lno++; +		if (list_channels) { +			printf("%3d %s", lno, line_buf); +		} +		else if (*chan_no) { +			if (*chan_no == lno) +				return line_buf; +		} +		else if ((strncasecmp(channel, line_buf, l) == 0) +				&& (line_buf[l] == ':')) { +			*chan_no = lno; +			return line_buf; +		} +	}; + +	return NULL; +} + + +int parse(const char *fname, int list_channels, int chan_no, const char *channel, +	  struct dvb_frontend_parameters *frontend, int *vpid, int *apid) +{ +	FILE *f; +	char *chan; +	char *name, *inv, *fec, *mod; + +	if ((f = fopen(fname, "r")) == NULL) { +		PERROR("could not open file '%s'", fname); +		return -1; +	} + +	chan = find_channel(f, list_channels, &chan_no, channel); +	fclose(f); +	if (list_channels) +		return 0; +	if (!chan) { +		ERROR("could not find channel '%s' in channel list", +		      channel); +		return -2; +	} +	printf("%3d %s", chan_no, chan); + +	if ((sscanf(chan, "%a[^:]:%d:%a[^:]:%d:%a[^:]:%a[^:]:%d:%d\n", +				&name, &frontend->frequency, +				&inv, &frontend->u.qam.symbol_rate, +				&fec, &mod, vpid, apid) != 8) +			|| !name || !inv || !fec | !mod) { +		ERROR("cannot parse service data"); +		return -3; +	} +	frontend->inversion = parse_param(inv, inversion_list, LIST_SIZE(inversion_list)); +	if (frontend->inversion < 0) { +		ERROR("inversion field syntax '%s'", inv); +		return -4; +	} +	frontend->u.qam.fec_inner = parse_param(fec, fec_list, LIST_SIZE(fec_list)); +	if (frontend->u.qam.fec_inner < 0) { +		ERROR("FEC field syntax '%s'", fec); +		return -5; +	} +	frontend->u.qam.modulation = parse_param(mod, modulation_list, +			LIST_SIZE(modulation_list)); +	if (frontend->u.qam.modulation < 0) { +		ERROR("modulation field syntax '%s'", mod); +		return -6; +	} +	printf("%3d %s: f %d, s %d, i %d, fec %d, qam %d, v %#x, a %#x\n", +			chan_no, name, frontend->frequency, frontend->u.qam.symbol_rate, +			frontend->inversion, frontend->u.qam.fec_inner, +			frontend->u.qam.modulation, *vpid, *apid); +	free(name); +	free(inv); +	free(fec); +	free(mod); + +	return 0; +} + + + +static +int set_pesfilter (int fd, int pid, dmx_pes_type_t type, int dvr) +{ +	struct dmx_pes_filter_params pesfilter; + +	if (pid <= 0 || pid >= 0x1fff) +		return 0; + +	pesfilter.pid = pid; +	pesfilter.input = DMX_IN_FRONTEND; +	pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER; +	pesfilter.pes_type = type; +	pesfilter.flags = DMX_IMMEDIATE_START; + +	if (ioctl(fd, DMX_SET_PES_FILTER, &pesfilter) < 0) { +		PERROR ("ioctl(DMX_SET_PES_FILTER) for %s PID failed", +			type == DMX_PES_AUDIO ? "Audio" : +			type == DMX_PES_VIDEO ? "Video" : "??"); +		return -1; +	} + +	return 0; +} + +static +int setup_frontend(int fe_fd, struct dvb_frontend_parameters *frontend) +{ +	struct dvb_frontend_info fe_info; + +	if (ioctl(fe_fd, FE_GET_INFO, &fe_info) < 0) { +		PERROR ("ioctl FE_GET_INFO failed"); +		return -1; +	} + +	if (fe_info.type != FE_QAM) { +		ERROR ("frontend device is not a QAM (DVB-C) device"); +		return -1; +	} + +	if (ioctl(fe_fd, FE_SET_FRONTEND, frontend) < 0) { +		PERROR ("ioctl FE_SET_FRONTEND failed"); +		return -1; +	} + +	return 0; +} + + +static +int check_frontend (int fe_fd) +{ +	fe_status_t status; +	uint16_t snr, signal; +	uint32_t ber, uncorrected_blocks; + +	do { +		ioctl(fe_fd, FE_READ_STATUS, &status); +		ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal); +		ioctl(fe_fd, FE_READ_SNR, &snr); +		ioctl(fe_fd, FE_READ_BER, &ber); +		ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks); + +		printf ("status %02x | signal %04x | snr %04x | " +			"ber %08x | unc %08x | ", +			status, signal, snr, ber, uncorrected_blocks); + +		if (status & FE_HAS_LOCK) +			printf("FE_HAS_LOCK"); + +		usleep(1000000); + +		printf("\n"); +	} while (1); + +	return 0; +} + + +static const char *usage = "\nusage: %s [-a adapter_num] [-f frontend_id] [-d demux_id] [-c conf_file] {<channel name>| -n channel_num}\n" +	"   or: %s [-c conf_file]  -l\n\n"; + + +int main(int argc, char **argv) +{ +	struct dvb_frontend_parameters frontend_param; +	char *homedir = getenv("HOME"); +	char *confname = NULL; +	char *channel = NULL; +	int adapter = 0, frontend = 0, demux = 0, dvr = 0; +	int vpid, apid; +	int frontend_fd, video_fd, audio_fd; +	int opt, list_channels = 0, chan_no = 0; + +        while ((opt = getopt(argc, argv, "ln:hrn:a:f:d:c:")) != -1) { +                switch (opt) { +                case 'a': +                        adapter = strtoul(optarg, NULL, 0); +                        break; +                case 'f': +                        frontend = strtoul(optarg, NULL, 0); +                        break; +                case 'd': +                        demux = strtoul(optarg, NULL, 0); +                        break; +                case 'r': +                        dvr = 1; +                        break; +                case 'l': +                        list_channels = 1; +                        break; +                case 'n': +                        chan_no = strtoul(optarg, NULL, 0); +                        break; +                case 'c': +                        confname = optarg; +                        break; +                case '?': +                case 'h': +                default: +                        fprintf (stderr, usage, argv[0], argv[0]); +                        return -1; +                }; +        } +	 +        if (optind < argc) +                channel = argv[optind]; + +        if (!channel && chan_no <= 0 && !list_channels) { +                fprintf (stderr, usage, argv[0], argv[0]); +                return -1; +        } + +	if (!homedir) +		ERROR("$HOME not set"); + +        snprintf (FRONTEND_DEV, sizeof(FRONTEND_DEV), +                  "/dev/dvb/adapter%i/frontend%i", adapter, frontend); + +        snprintf (DEMUX_DEV, sizeof(DEMUX_DEV), +                  "/dev/dvb/adapter%i/demux%i", adapter, demux); + +	printf ("using '%s' and '%s'\n", FRONTEND_DEV, DEMUX_DEV); + +	if (!confname) +	{ +		if (!homedir) +			ERROR("$HOME not set"); +		confname = malloc(strlen(homedir) + strlen(CHANNEL_FILE) + 1); +		memcpy(confname, homedir, strlen(homedir)); +		memcpy(confname + strlen(homedir), CHANNEL_FILE, +		       strlen(CHANNEL_FILE) + 1); +	} +	memset(&frontend_param, 0, sizeof(struct dvb_frontend_parameters)); + +	if (parse(confname, list_channels, chan_no, channel, &frontend_param, &vpid, &apid)) +		return -1; +	if (list_channels) +		return 0; + +	if ((frontend_fd = open(FRONTEND_DEV, O_RDWR)) < 0) { +		PERROR("failed opening '%s'", FRONTEND_DEV); +		return -1; +	} + +	if (setup_frontend(frontend_fd, &frontend_param) < 0) +		return -1; + +	if ((video_fd = open(DEMUX_DEV, O_RDWR)) < 0) { +		PERROR("failed opening '%s'", DEMUX_DEV); +		return -1; +	} + +	if (set_pesfilter (video_fd, vpid, DMX_PES_VIDEO, dvr) < 0) +		return -1; + +	if ((audio_fd = open(DEMUX_DEV, O_RDWR)) < 0) { +		PERROR("failed opening '%s'", DEMUX_DEV); +		return -1; +	} + +	if (set_pesfilter (audio_fd, apid, DMX_PES_AUDIO, dvr) < 0) +		return -1; + +	check_frontend (frontend_fd); + +	close (audio_fd); +	close (video_fd); +	close (frontend_fd); + +	return 0; +} + diff --git a/util/szap/femon.c b/util/szap/femon.c new file mode 100644 index 0000000..47e37a3 --- /dev/null +++ b/util/szap/femon.c @@ -0,0 +1,149 @@ +/* femon -- monitor frontend status + * + * Copyright (C) 2003 convergence GmbH + * Johannes Stezenbach <js@convergence.de> + * + * 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 <stdlib.h> +#include <limits.h> +#include <string.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/poll.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <stdint.h> +#include <sys/time.h> + +#include <linux/dvb/frontend.h> + +#ifndef TRUE +#define TRUE (1==1) +#endif +#ifndef FALSE +#define FALSE (1==0) +#endif + + +#define FRONTENDDEVICE "/dev/dvb/adapter%d/frontend%d" + +static char *usage_str = +    "\nusage: femon [options]\n" +    "     -a number : use given adapter (default 0)\n" +    "     -f number : use given frontend (default 0)\n\n"; + + +static void usage(void) +{ +   fprintf(stderr, usage_str); +   exit(1); +} + + +static +int check_frontend (int fe_fd) +{ +   fe_status_t status; +   uint16_t snr, signal; +   uint32_t ber, uncorrected_blocks; + +   do { +      ioctl(fe_fd, FE_READ_STATUS, &status); +      ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal); +      ioctl(fe_fd, FE_READ_SNR, &snr); +      ioctl(fe_fd, FE_READ_BER, &ber); +      ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks); + +      printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ", +	      status, signal, snr, ber, uncorrected_blocks); + +      if (status & FE_HAS_LOCK) +	 printf("FE_HAS_LOCK"); + +      printf("\n"); +      usleep(1000000); +   } while (1); + +   return 0; +} + + +static +int do_mon(unsigned int adapter, unsigned int frontend) +{ +   char fedev[128]; +   int fefd; +   int result; +   struct dvb_frontend_info fe_info; + +   snprintf(fedev, sizeof(fedev), FRONTENDDEVICE, adapter, frontend); +   printf("using '%s'\n", fedev); + +   if ((fefd = open(fedev, O_RDONLY | O_NONBLOCK)) < 0) { +      perror("opening frontend failed"); +      return FALSE; +   } + +   result = ioctl(fefd, FE_GET_INFO, &fe_info); + +   if (result < 0) { +      perror("ioctl FE_GET_INFO failed"); +      close(fefd); +      return FALSE; +   } + +   printf("FE: %s (%s)\n", fe_info.name, fe_info.type == FE_QPSK ? "SAT" : +		   fe_info.type == FE_QAM ? "CABLE": "TERRESTRIAL"); + +   check_frontend (fefd); + +   close(fefd); + +   return result; +} + +int main(int argc, char *argv[]) +{ +   unsigned int adapter = 0, frontend = 0; +   int opt; + +   while ((opt = getopt(argc, argv, "hlrn:a:f:d:")) != -1) { +      switch (opt) +      { +	 case '?': +	 case 'h': +	 default: +	    usage(); +	 case 'a': +	    adapter = strtoul(optarg, NULL, 0); +	    break; +	 case 'f': +	    frontend = strtoul(optarg, NULL, 0); +      } +   } + +   do_mon(adapter, frontend); + +   return FALSE; +} + diff --git a/util/szap/szap.c b/util/szap/szap.c new file mode 100644 index 0000000..581c970 --- /dev/null +++ b/util/szap/szap.c @@ -0,0 +1,560 @@ +/* szap -- simple zapping tool for the Linux DVB API + * + * szap operates on VDR (http://www.cadsoft.de/people/kls/vdr/index.htm) + * satellite channel lists (e.g. from http://www.dxandy.de/cgi-bin/dvbchan.pl). + * szap assumes you have a "Universal LNB" (i.e. with LOFs 9750/10600 MHz). + * + * Compilation: `gcc -Wall -I../../ost/include -O2 szap.c -o szap` + *  or, if your DVB driver is in the kernel source tree: + *              `gcc -Wall -DDVB_IN_KERNEL -O2 szap.c -o szap` + * + * Copyright (C) 2001 Johannes Stezenbach (js@convergence.de) + * for convergence integrated media + * + * 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 <stdlib.h> +#include <limits.h> +#include <string.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/poll.h> +#include <fcntl.h> +#include <time.h> +#include <unistd.h> + +#include <stdint.h> +#include <sys/time.h> + +#include <linux/dvb/frontend.h> +#include <linux/dvb/dmx.h> +#include "lnb.h" + +#ifndef TRUE +#define TRUE (1==1) +#endif +#ifndef FALSE +#define FALSE (1==0) +#endif + +/* location of channel list file */ +#define CHANNEL_FILE "channels.conf" + +/* one line of the VDR channel file has the following format: + * ^name:frequency_MHz:polarization:sat_no:symbolrate:vpid:apid:?:service_id$ + */ + + +#define FRONTENDDEVICE "/dev/dvb/adapter%d/frontend%d" +#define DEMUXDEVICE "/dev/dvb/adapter%d/demux%d" + +static struct lnb_types_st lnb_type; + +static int exit_after_tuning; +static int interactive; + +static char *usage_str = +    "\nusage: szap -q\n" +    "         list known channels\n" +    "       szap [options] {-n channel-number|channel_name}\n" +    "         zap to channel via number or full name (case insensitive)\n" +    "     -a number : use given adapter (default 0)\n" +    "     -f number : use given frontend (default 0)\n" +    "     -d number : use given demux (default 0)\n" +    "     -c file   : read channels list from 'file'\n" +    "     -x        : exit after tuning\n" +    "     -r        : set up /dev/dvb/adapterX/dvr0 for TS recording\n" +    "     -l lnb-type (DVB-S Only) (use -l help to print types) or \n" +    "     -l low[,high[,switch]] in Mhz\n" +    "     -i        : run interactively, allowing you to type in channel names\n" +    "                 or -n numbers for zapping\n"; + +static int set_demux(int dmxfd, int pid, int audio, int dvr) +{ +   struct dmx_pes_filter_params pesfilter; + +   if (pid <= 0 || pid >= 0x1fff) /* ignore this pid to allow radio services */ +	   return TRUE; + +   if (dvr) { +      int buffersize = 64 * 1024; +      if (ioctl(dmxfd, DMX_SET_BUFFER_SIZE, buffersize) == -1) +        perror("DMX_SET_BUFFER_SIZE failed"); +   } + +   pesfilter.pid = pid; +   pesfilter.input = DMX_IN_FRONTEND; +   pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER; +   pesfilter.pes_type = audio ? DMX_PES_AUDIO : DMX_PES_VIDEO; +   pesfilter.flags = DMX_IMMEDIATE_START; + +   if (ioctl(dmxfd, DMX_SET_PES_FILTER, &pesfilter) == -1) { +      fprintf(stderr, "DMX_SET_PES_FILTER failed " +	      "(PID = 0x%04x): %d %m\n", pid, errno); +      return FALSE; +   } + +   return TRUE; +} + + +struct diseqc_cmd { +   struct dvb_diseqc_master_cmd cmd; +   uint32_t wait; +}; + +void diseqc_send_msg(int fd, fe_sec_voltage_t v, struct diseqc_cmd *cmd, +		     fe_sec_tone_mode_t t, fe_sec_mini_cmd_t b) +{ +   if (ioctl(fd, FE_SET_TONE, SEC_TONE_OFF) == -1) +      perror("FE_SET_TONE failed"); +   if (ioctl(fd, FE_SET_VOLTAGE, v) == -1) +      perror("FE_SET_VOLTAGE failed"); +   usleep(15 * 1000); +   if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd) == -1) +      perror("FE_DISEQC_SEND_MASTER_CMD failed"); +   usleep(cmd->wait * 1000); +   usleep(15 * 1000); +   if (ioctl(fd, FE_DISEQC_SEND_BURST, b) == -1) +      perror("FE_DISEQC_SEND_BURST failed"); +   usleep(15 * 1000); +   if (ioctl(fd, FE_SET_TONE, t) == -1) +      perror("FE_SET_TONE failed"); +} + + + + +/* digital satellite equipment control, + * specification is available from http://www.eutelsat.com/ + */ +static int diseqc(int secfd, int sat_no, int pol_vert, int hi_band) +{ +   struct diseqc_cmd cmd = +       { {{0xe0, 0x10, 0x38, 0xf0, 0x00, 0x00}, 4}, 0 }; + +   /* param: high nibble: reset bits, low nibble set bits, +    * bits are: option, position, polarizaion, band +    */ +   cmd.cmd.msg[3] = +       0xf0 | (((sat_no * 4) & 0x0f) | (hi_band ? 1 : 0) | (pol_vert ? 0 : 2)); + +   diseqc_send_msg(secfd, pol_vert ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18, +		   &cmd, hi_band ? SEC_TONE_ON : SEC_TONE_OFF, +		   (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A); + +   return TRUE; +} + +static int do_tune(int fefd, unsigned int ifreq, unsigned int sr) +{ +   struct dvb_frontend_parameters tuneto; +   struct dvb_frontend_event ev; + +   /* discard stale QPSK events */ +   while (1) { +      if (ioctl(fefd, FE_GET_EVENT, &ev) == -1) +	 break; +   } + +   tuneto.frequency = ifreq; +   tuneto.inversion = INVERSION_AUTO; +   tuneto.u.qpsk.symbol_rate = sr; +   tuneto.u.qpsk.fec_inner = FEC_AUTO; + +   if (ioctl(fefd, FE_SET_FRONTEND, &tuneto) == -1) { +      perror("FE_SET_FRONTEND failed"); +      return FALSE; +   } + +   return TRUE; +} + + +static +int check_frontend (int fe_fd, int dvr) +{ +   fe_status_t status; +   uint16_t snr, signal; +   uint32_t ber, uncorrected_blocks; +   int timeout = 0; + +   do { +      if (ioctl(fe_fd, FE_READ_STATUS, &status) == -1) +         perror("FE_READ_STATUS failed"); +      /* some frontends might not support all these ioctls, thus we +       * avoid printing errors */ +      if (ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal) == -1) +         signal = -2; +      if (ioctl(fe_fd, FE_READ_SNR, &snr) == -1) +         snr = -2; +      if (ioctl(fe_fd, FE_READ_BER, &ber) == -1) +         ber = -2; +      if (ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks) == -1) +         uncorrected_blocks = -2; + +      printf ("status %02x | signal %04x | snr %04x | ber %08x | unc %08x | ", +	      status, signal, snr, ber, uncorrected_blocks); + +      if (status & FE_HAS_LOCK) +	 printf("FE_HAS_LOCK"); +      printf("\n"); + +      if (exit_after_tuning && ((status & FE_HAS_LOCK) || (++timeout >= 10))) +         break; + +      usleep(1000000); +   } while (1); + +   return 0; +} + + +static +int zap_to(unsigned int adapter, unsigned int frontend, unsigned int demux, +      unsigned int sat_no, unsigned int freq, unsigned int pol, +      unsigned int sr, unsigned int vpid, unsigned int apid, int dvr) +{ +   char fedev[128], dmxdev[128]; +   static int fefd, videofd, audiofd; +   uint32_t ifreq; +   int hiband, result; +   static struct dvb_frontend_info fe_info; + +   if (!fefd) { +      snprintf(fedev, sizeof(fedev), FRONTENDDEVICE, adapter, frontend); +      snprintf(dmxdev, sizeof(dmxdev), DEMUXDEVICE, adapter, demux); +      printf("using '%s' and '%s'\n", fedev, dmxdev); + +      if ((fefd = open(fedev, O_RDWR | O_NONBLOCK)) < 0) { +	 perror("opening frontend failed"); +	 return FALSE; +      } + +      result = ioctl(fefd, FE_GET_INFO, &fe_info); + +      if (result < 0) { +	 perror("ioctl FE_GET_INFO failed"); +	 close(fefd); +	 return FALSE; +      } + +      if (fe_info.type != FE_QPSK) { +	 fprintf(stderr, "frontend device is not a QPSK (DVB-S) device!\n"); +	 close(fefd); +	 return FALSE; +      } + +      if ((videofd = open(dmxdev, O_RDWR)) < 0) { +	 perror("opening video demux failed"); +	 close(fefd); +	 return FALSE; +      } + +      if ((audiofd = open(dmxdev, O_RDWR)) < 0) { +	 perror("opening audio demux failed"); +	 close(videofd); +	 close(fefd); +	 return FALSE; +      } +   } + +   hiband = 0; +   if (lnb_type.switch_val && lnb_type.high_val && +	freq >= lnb_type.switch_val) +	hiband = 1; + +   if (hiband) +      ifreq = freq - lnb_type.high_val; +   else { +      if (freq < lnb_type.low_val) +          ifreq = lnb_type.low_val - freq; +      else +          ifreq = freq - lnb_type.low_val; +   } +   result = FALSE; + +   if (diseqc(fefd, sat_no, pol, hiband)) +      if (do_tune(fefd, ifreq, sr)) +	 if (set_demux(videofd, vpid, 0, dvr)) +	    if (set_demux(audiofd, apid, 1, dvr)) +	       result = TRUE; + +   check_frontend (fefd, dvr); + +   if (!interactive) { +      close(audiofd); +      close(videofd); +      close(fefd); +   } + +   return result; +} + + +static int read_channels(const char *filename, int list_channels, +			 uint32_t chan_no, const char *chan_name, +			 unsigned int adapter, unsigned int frontend, +			 unsigned int demux, int dvr) +{ +   FILE *cfp; +   char buf[4096]; +   char inp[256]; +   char *field, *tmp, *p; +   unsigned int line; +   unsigned int freq, pol, sat_no, sr, vpid, apid; +   int ret; + +again: +   line = 0; +   if (!(cfp = fopen(filename, "r"))) { +      fprintf(stderr, "error opening channel list '%s': %d %m\n", +	      filename, errno); +      return FALSE; +   } + +   if (interactive) { +      fprintf(stderr, "\n>>> "); +      if (!fgets(inp, sizeof(inp), stdin)) { +	 printf("\n"); +	 return -1; +      } +      if (inp[0] == '-' && inp[1] == 'n') { +	 chan_no = strtoul(inp+2, NULL, 0); +	 chan_name = NULL; +	 if (!chan_no) { +	    fprintf(stderr, "bad channel number\n"); +	    goto again; +	 } +      } else { +	 p = strchr(inp, '\n'); +	 if (p) +	    *p = '\0'; +	 chan_name = inp; +	 chan_no = 0; +      } +   } + +   while (!feof(cfp)) { +      if (fgets(buf, sizeof(buf), cfp)) { +	 line++; + +	 if (chan_no && chan_no != line) +	    continue; + +	 tmp = buf; +	 field = strsep(&tmp, ":"); + +	 if (!field) +	    goto syntax_err; + +	 if (list_channels) { +	    printf("%03u %s\n", line, field); +	    continue; +	 } + +	 if (chan_name && strcasecmp(chan_name, field) != 0) +	    continue; + +	 printf("zapping to %d '%s':\n", line, field); + +	 if (!(field = strsep(&tmp, ":"))) +	    goto syntax_err; + +	 freq = strtoul(field, NULL, 0); + +	 if (!(field = strsep(&tmp, ":"))) +	    goto syntax_err; + +	 pol = (field[0] == 'h' ? 0 : 1); + +	 if (!(field = strsep(&tmp, ":"))) +	    goto syntax_err; + +	 sat_no = strtoul(field, NULL, 0); + +	 if (!(field = strsep(&tmp, ":"))) +	    goto syntax_err; + +	 sr = strtoul(field, NULL, 0) * 1000; + +	 if (!(field = strsep(&tmp, ":"))) +	    goto syntax_err; + +	 vpid = strtoul(field, NULL, 0); + +	 if (!(field = strsep(&tmp, ":"))) +	    goto syntax_err; + +	 apid = strtoul(field, NULL, 0); + +	 printf("sat %u, frequency = %u MHz %c, symbolrate %u, " +		"vpid = 0x%04x, apid = 0x%04x\n", +		sat_no, freq, pol ? 'V' : 'H', sr, vpid, apid); + +	 fclose(cfp); + +	 ret = zap_to(adapter, frontend, demux, +		      sat_no, freq * 1000, pol, sr, vpid, apid, dvr); +	 if (interactive) +	    goto again; + +	 if (ret) +	    return TRUE; + +	 return FALSE; + +       syntax_err: +	 fprintf(stderr, "syntax error in line %u: '%s'\n", line, buf); +      } else if (ferror(cfp)) { +	 fprintf(stderr, "error reading channel list '%s': %d %m\n", +		 filename, errno); +	 fclose(cfp); +	 return FALSE; +      } else +	 break; +   } + +   fclose(cfp); + +   if (!list_channels) { +      fprintf(stderr, "channel not found\n"); +      if (!interactive) +	 return FALSE; +   } +   if (interactive) +      goto again; + +   return TRUE; +} + + +void +bad_usage(char *pname, int prlnb) +{ +int i; +struct lnb_types_st *lnbp; +char **cp; + +	if (!prlnb) { +		fprintf (stderr, usage_str, pname); +	} else { +		i = 0; +		fprintf(stderr, "-l <lnb-type> or -l low[,high[,switch]] in Mhz\nwhere <lnb-type> is:\n"); +		while(NULL != (lnbp = lnb_enum(i))) { +			fprintf (stderr, "%s\n", lnbp->name); +			for (cp = lnbp->desc; *cp ; cp++) { +				fprintf (stderr, "   %s\n", *cp); +			} +			i++; +		} +	} +} + +int main(int argc, char *argv[]) +{ +   const char *home; +   char chanfile[2 * PATH_MAX]; +   int list_channels = 0; +   unsigned int chan_no = 0; +   const char *chan_name = NULL; +   unsigned int adapter = 0, frontend = 0, demux = 0, dvr = 0; +   int opt, copt = 0; + +   lnb_type = *lnb_enum(0); +   while ((opt = getopt(argc, argv, "hqrn:a:f:d:c:l:xi")) != -1) { +      switch (opt) +      { +	 case '?': +	 case 'h': +	 default: +	    bad_usage(argv[0], 0); +	 case 'q': +	    list_channels = 1; +	    break; +	 case 'r': +	    dvr = 1; +	    break; +	 case 'n': +	    chan_no = strtoul(optarg, NULL, 0); +	    break; +	 case 'a': +	    adapter = strtoul(optarg, NULL, 0); +	    break; +	 case 'f': +	    frontend = strtoul(optarg, NULL, 0); +	    break; +	 case 'd': +	    demux = strtoul(optarg, NULL, 0); +	    break; +	 case 'c': +	    copt = 1; +	    strncpy(chanfile, optarg, sizeof(chanfile)); +	    break; +	 case 'l': +	    if (lnb_decode(optarg, &lnb_type) < 0) { +		bad_usage(argv[0], 1); +		return -1; +	    } +	    break; +	 case 'x': +	    exit_after_tuning = 1; +	    break; +	 case 'i': +	    interactive = 1; +	    exit_after_tuning = 1; +      } +   } +   lnb_type.low_val *= 1000;	/* convert to kiloherz */ +   lnb_type.high_val *= 1000;	/* convert to kiloherz */ +   lnb_type.switch_val *= 1000;	/* convert to kiloherz */ +   if (optind < argc) +      chan_name = argv[optind]; +   if (chan_name && chan_no) { +	bad_usage(argv[0], 0); +	return -1; +   } +   if (list_channels && (chan_name || chan_no)) { +	bad_usage(argv[0], 0); +	return -1; +   } +   if (!list_channels && !chan_name && !chan_no && !interactive) { +	bad_usage(argv[0], 0); +	return -1; +   } + +   if (!copt) { +       if (!(home = getenv("HOME"))) { +          fprintf(stderr, "error: $HOME not set\n"); +          return TRUE; +       } +       strncpy(chanfile, home, sizeof(chanfile)); +       strcat(chanfile, "/.szap/" CHANNEL_FILE); +   } + +   printf("reading channels from file '%s'\n", chanfile); + +   if (!read_channels(chanfile, list_channels, chan_no, chan_name, +	    adapter, frontend, demux, dvr)) +      return TRUE; + +   return FALSE; +} + diff --git a/util/szap/tzap.c b/util/szap/tzap.c new file mode 100644 index 0000000..2527c23 --- /dev/null +++ b/util/szap/tzap.c @@ -0,0 +1,477 @@ +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <unistd.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <stdio.h> +#include <fcntl.h> +#include <ctype.h> +#include <errno.h> + +#include <linux/dvb/frontend.h> +#include <linux/dvb/dmx.h> + + +static char FRONTEND_DEV [80]; +static char DEMUX_DEV [80]; + +#define CHANNEL_FILE "/.tzap/channels.conf" + +#define ERROR(x...)                                                     \ +        do {                                                            \ +                fprintf(stderr, "ERROR: ");                             \ +                fprintf(stderr, x);                                     \ +                fprintf (stderr, "\n");                                 \ +        } while (0) + +#define PERROR(x...)                                                    \ +        do {                                                            \ +                fprintf(stderr, "ERROR: ");                             \ +                fprintf(stderr, x);                                     \ +                fprintf (stderr, " (%s)\n", strerror(errno));		\ +        } while (0) + + +typedef struct { +	char *name; +	int value; +} Param; + +static const Param inversion_list [] = { +	{ "INVERSION_OFF", INVERSION_OFF }, +	{ "INVERSION_ON", INVERSION_ON }, +	{ "INVERSION_AUTO", INVERSION_AUTO } +}; + +static const Param bw_list [] = { +	{ "BANDWIDTH_6_MHZ", BANDWIDTH_6_MHZ }, +	{ "BANDWIDTH_7_MHZ", BANDWIDTH_7_MHZ }, +	{ "BANDWIDTH_8_MHZ", BANDWIDTH_8_MHZ } +}; + +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 guard_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 transmissionmode_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 (int fd, const Param * plist, int list_size, int *param) +{ +	char c; +	int character = 0; +	int index = 0; + +	while (1) { +		if (read(fd, &c, 1) < 1) +			return -1;	/*  EOF? */ + +		if ((c == ':' || c == '\n') +		    && plist->name[character] == '\0') +			break; + +		while (toupper(c) != plist->name[character]) { +			index++; +			plist++; +			if (index >= list_size)	 /*  parse error, no valid */ +				return -2;	 /*  parameter name found  */ +		} + +		character++; +	} + +	*param = plist->value; + +	return 0; +} + + +static +int parse_int(int fd, int *val) +{ +	char number[11];	/* 2^32 needs 10 digits... */ +	int character = 0; + +	while (1) { +		if (read(fd, &number[character], 1) < 1) +			return -1;	/*  EOF? */ + +		if (number[character] == ':' || number[character] == '\n') { +			number[character] = '\0'; +			break; +		} + +		if (!isdigit(number[character])) +			return -2;	/*  parse error, not a digit... */ + +		character++; + +		if (character > 10)	/*  overflow, number too big */ +			return -3;	/*  to fit in 32 bit */ +	}; + +	*val = strtol(number, NULL, 10); + +	return 0; +} + + +static +int find_channel(int fd, const char *channel) +{ +	int character = 0; + +	while (1) { +		char c; + +		if (read(fd, &c, 1) < 1) +			return -1;	/*  EOF! */ + +		if (c == ':' && channel[character] == '\0') +			break; + +		if (toupper(c) == toupper(channel[character])) +			character++; +		else +			character = 0; +	}; + +	return 0; +} + + +static +int try_parse_int(int fd, int *val, const char *pname) +{ +	int err; + +	err = parse_int(fd, val); + +	if (err) +		ERROR("error while parsing %s (%s)", pname, +		      err == -1 ? "end of file" : +		      err == -2 ? "not a number" : "number too big"); + +	return err; +} + + +static +int try_parse_param(int fd, const Param * plist, int list_size, int *param, +		    const char *pname) +{ +	int err; + +	err = parse_param(fd, plist, list_size, param); + +	if (err) +		ERROR("error while parsing %s (%s)", pname, +		      err == -1 ? "end of file" : "syntax error"); + +	return err; +} + + +int parse(const char *fname, const char *channel, +	  struct dvb_frontend_parameters *frontend, int *vpid, int *apid) +{ +	int fd; +	int err; + +	if ((fd = open(fname, O_RDONLY | O_NONBLOCK)) < 0) { +		PERROR ("could not open file '%s'", fname); +		perror (""); +		return -1; +	} + +	if (find_channel(fd, channel) < 0) { +		ERROR("could not find channel '%s' in channel list", channel); +		return -2; +	} + +	if ((err = try_parse_int(fd, &frontend->frequency, "frequency"))) +		return -3; + +	if ((err = try_parse_param(fd, +				   inversion_list, LIST_SIZE(inversion_list), +				   (int *) &frontend->inversion, +				   "inversion"))) +		return -4; + +	if ((err = try_parse_param(fd, bw_list, LIST_SIZE(bw_list), +				   (int *) &frontend->u.ofdm.bandwidth, +				   "bandwidth"))) +		return -5; + +	if ((err = try_parse_param(fd, fec_list, LIST_SIZE(fec_list), +				   (int *) &frontend->u.ofdm.code_rate_HP, +				   "code_rate_HP"))) +		return -6; + +	if ((err = try_parse_param(fd, fec_list, LIST_SIZE(fec_list), +				   (int *) &frontend->u.ofdm.code_rate_LP, +				   "code_rate_LP"))) +		return -7; + +	if ((err = try_parse_param(fd, constellation_list, +				   LIST_SIZE(constellation_list), +				   (int *) &frontend->u.ofdm.constellation, +				   "constellation"))) +		return -8; + +	if ((err = try_parse_param(fd, transmissionmode_list, +				   LIST_SIZE(transmissionmode_list), +				   (int *) &frontend->u.ofdm. +				   transmission_mode, +				   "transmission_mode"))) +		return -9; + +	if ((err = try_parse_param(fd, guard_list, LIST_SIZE(guard_list), +				   (int *) &frontend->u.ofdm. +				   guard_interval, "guard_interval"))) +		return -10; + +	if ((err = try_parse_param(fd, hierarchy_list, +				   LIST_SIZE(hierarchy_list), +				   (int *) &frontend->u.ofdm. +				   hierarchy_information, +				   "hierarchy_information"))) +		return -11; + +	if ((err = try_parse_int(fd, vpid, "Video PID"))) +		return -12; + +	if ((err = try_parse_int(fd, apid, "Audio PID"))) +		return -13; + +	close(fd); + +	return 0; +} + + +static +int set_pesfilter (int fd, int pid, dmx_pes_type_t type, int dvr) +{ +        struct dmx_pes_filter_params pesfilter; + +        if (pid <= 0 || pid >= 0x1fff) +                return 0; + +        pesfilter.pid = pid; +        pesfilter.input = DMX_IN_FRONTEND; +        pesfilter.output = dvr ? DMX_OUT_TS_TAP : DMX_OUT_DECODER; +        pesfilter.pes_type = type; +        pesfilter.flags = DMX_IMMEDIATE_START; + +        if (ioctl(fd, DMX_SET_PES_FILTER, &pesfilter) < 0) { +                PERROR ("ioctl(DMX_SET_PES_FILTER) for %s PID failed", +                        type == DMX_PES_AUDIO ? "Audio" : +                        type == DMX_PES_VIDEO ? "Video" : "??"); +                return -1; +        } + +        return 0; +} + + +static +int setup_frontend (int fe_fd, struct dvb_frontend_parameters *frontend) +{ +	struct dvb_frontend_info fe_info; + +	if (ioctl(fe_fd, FE_GET_INFO, &fe_info) < 0) { +		PERROR("ioctl FE_GET_INFO failed"); +		return -1; +	} + +	if (fe_info.type != FE_OFDM) { +		ERROR ("frontend device is not a OFDM (DVB-T) device"); +		return -1; +	} + +	printf ("tuning to %i Hz\n", frontend->frequency); + +	if (ioctl(fe_fd, FE_SET_FRONTEND, frontend) < 0) { +		PERROR("ioctl FE_SET_FRONTEND failed"); +		return -1; +	} + +	return 0; +} + + +static +int check_frontend (int fe_fd) +{ +	fe_status_t status; +	uint16_t snr, signal; +	uint32_t ber, uncorrected_blocks; + +	do { +		ioctl(fe_fd, FE_READ_STATUS, &status); +		ioctl(fe_fd, FE_READ_SIGNAL_STRENGTH, &signal); +		ioctl(fe_fd, FE_READ_SNR, &snr); +		ioctl(fe_fd, FE_READ_BER, &ber); +		ioctl(fe_fd, FE_READ_UNCORRECTED_BLOCKS, &uncorrected_blocks); + +		printf ("status %02x | signal %04x | snr %04x | " +			"ber %08x | unc %08x | ", +			status, signal, snr, ber, uncorrected_blocks); + +		if (status & FE_HAS_LOCK) +			printf("FE_HAS_LOCK"); + +		usleep(1000000); + +		printf("\n"); +	} while (1); + +	return 0; +} + + +static const char *usage = "\nusage: %s [-a adapter_num] [-f frontend_id] [-d demux_id] [-c conf_file] [-r] <channel name>\n\n"; + + +int main(int argc, char **argv) +{ +	struct dvb_frontend_parameters frontend_param; +	char *homedir = getenv ("HOME"); +	char *confname = NULL; +	char *channel = NULL; +	int adapter = 0, frontend = 0, demux = 0, dvr = 0; +	int vpid, apid; +	int frontend_fd, audio_fd, video_fd; +	int opt; + +	while ((opt = getopt(argc, argv, "hrn:a:f:d:c:")) != -1) { +		switch (opt) { +		case 'a': +			adapter = strtoul(optarg, NULL, 0); +			break; +		case 'f': +			frontend = strtoul(optarg, NULL, 0); +			break; +		case 'd': +			demux = strtoul(optarg, NULL, 0); +			break; +		case 'r': +			dvr = 1; +			break; +		case 'c': +			confname = optarg; +			break; +		case '?': +		case 'h': +		default: +			fprintf (stderr, usage, argv[0]); +			return -1; +		}; +	} + +	if (optind < argc) +		channel = argv[optind]; + +	if (!channel) { +		fprintf (stderr, usage, argv[0]); +		return -1; +	} + +	snprintf (FRONTEND_DEV, sizeof(FRONTEND_DEV), +		  "/dev/dvb/adapter%i/frontend%i", adapter, frontend); + +	snprintf (DEMUX_DEV, sizeof(DEMUX_DEV), +		  "/dev/dvb/adapter%i/demux%i", adapter, demux); + +	printf ("using '%s' and '%s'\n", FRONTEND_DEV, DEMUX_DEV); + +	if (!confname) +	{ +		if (!homedir) +			ERROR ("$HOME not set"); +		confname = malloc (strlen(homedir) + strlen(CHANNEL_FILE) + 1); +		memcpy (confname, homedir, strlen(homedir)); +		memcpy (confname + strlen(homedir), CHANNEL_FILE, +	        	strlen(CHANNEL_FILE) + 1); +	} + +	memset(&frontend_param, 0, sizeof(struct dvb_frontend_parameters)); + +	if (parse (confname, channel, &frontend_param, &vpid, &apid)) +		return -1; + +	if ((frontend_fd = open(FRONTEND_DEV, O_RDWR)) < 0) { +		PERROR ("failed opening '%s'", FRONTEND_DEV); +		return -1; +	} + +	if (setup_frontend (frontend_fd, &frontend_param) < 0) +		return -1; + +        if ((video_fd = open(DEMUX_DEV, O_RDWR)) < 0) { +                PERROR("failed opening '%s'", DEMUX_DEV); +                return -1; +        } + +	printf ("video pid 0x%04x, audio pid 0x%04x\n", vpid, apid); +	if (set_pesfilter (video_fd, vpid, DMX_PES_VIDEO, dvr) < 0) +		return -1; + +	if ((audio_fd = open(DEMUX_DEV, O_RDWR)) < 0) { +                PERROR("failed opening '%s'", DEMUX_DEV); +                return -1; +        } + +	if (set_pesfilter (audio_fd, apid, DMX_PES_AUDIO, dvr) < 0) +		return -1; + +	check_frontend (frontend_fd); + +	close (audio_fd); +	close (video_fd); +	close (frontend_fd); + +	return 0; +} + diff --git a/util/ttusb_dec_reset/Makefile b/util/ttusb_dec_reset/Makefile new file mode 100644 index 0000000..cde7de5 --- /dev/null +++ b/util/ttusb_dec_reset/Makefile @@ -0,0 +1,17 @@ +CC	= gcc +RM	= rm -f +CFLAGS	= -g -Wall -O2 +LFLAGS	= -g -Wall +LDFLAGS = -lusb + +OBJS	= ttusb_dec_reset.o +TARGET	= ttusb_dec_reset + +$(TARGET): $(OBJS) +	$(CC) $(LFLAGS) $(LDFLAGS) -o $(TARGET) $(OBJS) + +.c.o: +	$(CC) $(CFLAGS) -c $< -o $@ + +clean: +	$(RM) *.o $(TARGET) diff --git a/util/ttusb_dec_reset/README b/util/ttusb_dec_reset/README new file mode 100644 index 0000000..50db265 --- /dev/null +++ b/util/ttusb_dec_reset/README @@ -0,0 +1,28 @@ +Hello, + +In theory the driver could be made to send the DEC the reset sequence when +all devices were closed.  However, due to the awkwardness of switching +between slave and stand-alone mode, I've decided against this.  Hence this +application, which I hope provides the user a nice compromise between +control and ease-of-use. + +ttusb_dec_reset is a small utility for resetting a ttusb-dec device to +stand-alone mode after use.  It requires libusb, which can be found here: + +http://libusb.sourceforge.net/ + +There is probably a package for it included with your linux distribution +though. + +For the utility to reset a device, it must have permission to access the usb +device, and the device must not be claimed by anything else.  That means that +the ttusb-dec module must be rmmoded before using this utility.  You probably +want to have turned off any hotplug mechanisms before running the utility +or the device will likely get taken over again once it comes back up.  Or you +could just yank the usb cable out. + +The utility takes no arguments, you just run it: +./ttusb_dec_reset + +Cheers, +Alex diff --git a/util/ttusb_dec_reset/ttusb_dec_reset.c b/util/ttusb_dec_reset/ttusb_dec_reset.c new file mode 100644 index 0000000..51ddfc7 --- /dev/null +++ b/util/ttusb_dec_reset/ttusb_dec_reset.c @@ -0,0 +1,53 @@ +#include <stdio.h> +#include <usb.h> + +void dec_reset(struct usb_device *dev) +{ +	char message[] = {0xaa, 0x00, 0xf1, 0x01, 0x00}; +	usb_dev_handle *handle = usb_open(dev); + +	printf("Device found.\n"); + +	if (handle) { +		if (!usb_claim_interface(handle, 0)) { +			int result; +			printf("Reseting device.. "); +			result = usb_bulk_write(handle, 3, message, +						sizeof(message), 1000); +			if (result >= 0) +				printf("succeeded.\n"); +			else +				printf("failed. (Error code: %d)\n", result); +		} else { +			printf("Couldn't claim interface.\n"); +		} +		usb_close(handle); +	} +} + +int main() +{ +	struct usb_bus *busses; +	struct usb_bus *bus; + +	usb_init(); +	usb_find_busses(); +	usb_find_devices(); + +	busses = usb_get_busses(); + +	for (bus = busses; bus; bus = bus->next) { +		struct usb_device *dev; + +		for (dev = bus->devices; dev; dev = dev->next) { +			if (dev->descriptor.idVendor == 0x0b48 && +			    (dev->descriptor.idProduct == 0x1006 || +			     dev->descriptor.idProduct == 0x1008 || +			     dev->descriptor.idProduct == 0x1009)) { +				dec_reset(dev); +			} +		} +	} + +	return 0; +} | 
