dvbtune-0.5/0000755000076400017500000000000010012451731012703 5ustar davedave00000000000000dvbtune-0.5/scripts/0000755000076400017500000000000010012451731014372 5ustar davedave00000000000000dvbtune-0.5/scripts/astra19.txt0000644000076400017500000000150107470510067016430 0ustar davedave0000000000000010788000 v 22000 10832000 h 22000 11719000 h 27500 11758000 h 27500 11817000 v 27500 11836000 h 27500 11856000 v 27500 11876000 h 27500 11914000 h 27500 11934000 v 27500 11954000 h 27500 11973000 v 27500 11992000 h 27500 12012000 v 27500 12032000 h 27500 12051000 v 27500 12070000 h 27500 12090000 v 27500 12110000 h 27500 12129000 v 27500 12148000 h 27500 12168000 v 27500 12188000 h 27500 12207000 v 27500 12226000 h 27500 12246000 v 27500 12266000 h 27500 12285000 v 27500 12304000 h 27500 12324000 v 27500 12344000 h 27500 12363000 v 27500 12382000 h 27500 12402000 v 27500 12422000 h 27500 12441000 v 27500 12460000 h 27500 12480000 v 27500 12515000 h 22000 12522000 v 22000 12552000 v 22000 12574000 h 22000 12581000 v 22000 12604000 h 22000 12611000 v 22000 12670000 v 22000 12692000 h 22000 12699000 v 22000 12722000 h 22000 dvbtune-0.5/scripts/README0000644000076400017500000000116107470510067015265 0ustar davedave00000000000000This directory contains some example scripts to produce full XML files for various satellites and DVB-T transmitters. check.sh - Read a list of satellite transponders (freq, pol, srate) and create an XML file containing the details for all transponders. A transponder list for Astra 19 is included. scan_uk-t.sh Scan the UK Crystal Palace transmitter for channels. Change the frequencies in this script for your local DVB-T transmitter. (see the links at http://www.linuxstb.org/dvb-t/ Please send any scripts to dave@dchapman.com for inclusion in future releases. dvbtune-0.5/scripts/astra28.txt0000644000076400017500000000175207501747745016452 0ustar davedave0000000000000010744000 h 22000 10832000 h 22000 10847000 v 22000 10862000 h 22000 10876000 v 22000 10891000 h 22000 10906000 v 22000 10921000 h 22000 10936000 v 22000 11469000 h 27500 11508000 h 27500 11527000 v 27500 11546000 h 27500 11565000 v 27500 11585000 h 27500 11623000 h 27500 11662000 h 27500 11681000 v 27500 11720000 h 27500 11739000 v 27500 11758000 h 27500 11778000 v 27500 11798000 h 27500 11817000 v 27500 11836000 h 27500 11856000 v 27500 11876000 h 27500 11895000 v 27500 11914000 h 27500 11934000 v 27500 11954000 h 27500 11973000 v 27500 11992000 h 27500 12012000 v 27500 12032000 h 27500 12051000 v 27500 12070000 h 27500 12090000 v 27500 12110000 h 27500 12129000 v 27500 12148000 h 27500 12168000 v 27500 12188000 h 27500 12207000 v 27500 12226000 h 27500 12246000 v 27500 12266000 h 27500 12285000 v 27500 12304000 h 27500 12324000 v 27500 12344000 h 27500 12363000 v 27500 12382000 h 27500 12402000 v 27500 12422000 h 27500 12460000 h 27500 12480000 v 27500 12575000 v 2894 12607000 h 27500 dvbtune-0.5/scripts/check.sh0000755000076400017500000000073507470510066016026 0ustar davedave00000000000000#!/bin/sh # # Read a file containing "FREQ POL SRATE" lines and produce a # XML file containing the DVB-SI data. # # Usage: ./check.sh < astra19.txt > astra19.xml # # Change the DVBTUNE variable to point to your installed version of dvbtune # Change CARD to be 0 (first card), 1 (second card), 2 (third card) etc DVBTUNE=../dvbtune CARD=0 echo '' echo '' while read x y z do $DVBTUNE -c $CARD -f $x -p $y -s $z -i done echo '' dvbtune-0.5/scripts/scan_ge_c.sh0000644000076400017500000000234707532171472016653 0ustar davedave00000000000000#!/bin/sh # Scan German Cable TV broadcasts. # NOTE: CHANGE CARD TO SUIT YOUR SYSTEM - FIRST CARD IS "0", SECOND IS "1" etc CARD=0 DVBTUNE=../dvbtune XML2VDR=../xml2vdr get_frequency_list() { cat << END | grep -v "^#" #322000000 #330000000 #338000000 346000000 354000000 362000000 370000000 378000000 #386000000 394000000 402000000 410000000 426000000 434000000 442000000 #450000000 END } get_frequency_list_test() { cat << END | grep -v "^#" 346000000 END } get_channels() { echo '' echo '' get_frequency_list | while read frequency; do $DVBTUNE -c $CARD -f $frequency -i -s 6900 sleep 1 done echo '' } LISTXMLORIG="`get_channels`" echo "$LISTXMLORIG" >listorig.xml LISTXML="`echo "$LISTXMLORIG" | tr -d '\206\207\005' | sed 's/Ö/Oe/g' | sed 's/Ä/Ae/g' | sed 's/Ü/ue/g' | sed 's/ä/Ae/g' | sed 's/ö/Oe/g' | sed 's/ü/ue/g' `" echo "$LISTXML" >list.xml LISTVDR="`echo "$LISTXML" | $XML2VDR - | sed 's/\&/\&/g' | sed 's/000:/:/g`" echo "$LISTVDR" >list.vdr # Sort output echo ":Television" echo "$LISTVDR" | grep -i "(TV)" | sed 's/ (TV)//g' | sed 's/^ *//g' | sed 's/::/:0:/g' echo ":Radio" echo "$LISTVDR" | grep -i "(RADIO)" | sed 's/ (RADIO)//g' | sed 's/^ *//g' | sed 's/::/:0:/g' dvbtune-0.5/scripts/scan_uk-t.sh0000755000076400017500000000153207554110775016637 0ustar davedave00000000000000#!/bin/sh # Scan the UK DVB-T broadcasts from the Crystal Palace transmitter # # USAGE: ./scan_uk-t.sh > channels.xml # ../xml2vdr channels.xml > channels.conf # # See http://www.linuxstb.org/dvb-t/ for instructions on how to find # the frequencies for your local transmitter. # # If you are a DVB-T user outside the UK, you will need to amend tune.c # with the detailed tuning parameters for your country. # NOTE: CHANGE CARD TO SUIT YOUR SYSTEM - FIRST CARD IS "0", SECOND IS "1" etc CARD=0 DVBTUNE=../dvbtune echo '' echo '' $DVBTUNE -c $CARD -f 505833333 -qam 16 -cr 3_4 -i $DVBTUNE -c $CARD -f 481833333 -i $DVBTUNE -c $CARD -f 561833333 -i $DVBTUNE -c $CARD -f 529833333 -qam 16 -cr 3_4 -i $DVBTUNE -c $CARD -f 578166667 -qam 16 -cr 3_4 -i $DVBTUNE -c $CARD -f 537833333 -qam 16 -cr 3_4 -i echo '' dvbtune-0.5/Makefile0000644000076400017500000000120307552007243014351 0ustar davedave00000000000000INCS=-I /usr/include/libxml2 CFLAGS= -Wall $(INCS) CC=gcc all: dvbtune # Delete the following line if you are not using a # "NEWSTRUCT" driver. If you are using a "NEWSTRUCT" # driver, it must be later than October 10th 2002 NEWSTRUCT=1 ifdef NEWSTRUCT CFLAGS += -DNEWSTRUCT INCS += -I ../DVB/include else INCS += -I ../DVB/ost/include endif ifdef UK CFLAGS += -DUK endif ifdef FINLAND CFLAGS += -DFINLAND endif ifdef FINLAND2 CFLAGS += -DFINLAND2 endif tune.o: tune.c tune.h dvb_defaults.h dvbtune: dvbtune.c tune.o xml2vdr: xml2vdr.c $(CC) $(CFLAGS) -o xml2vdr xml2vdr.c -lxml2 clean: rm -f *.o *~ dvbtune xml2vdr dvbtune-0.5/README0000644000076400017500000000723310012450527013572 0ustar davedave00000000000000DVBtune 0.5 ----------- DVBtune is a simple tuning application for DVB cards supported by the Linux DVB driver (www.linuxtv.org). This is still very experimental - especially the XML output. The latest release can be found at www.linuxstb.org. You can contact the author at . There is also a CVS repository (normally more recent than linuxstb.org) available at http://sourceforge.net/projects/dvbtools Installation ------------ The package includes two applications - dvbtune and xml2vdr. dvbtune has the option to dump the metadata from a DVB transponder/multiplex into an XML file. This XML file is hopefully self-explanatory (i.e. I am too lazy to write documentation for it), and should be read in conjunction with the DVB-SI standard (EN 300 468) available from www.etsi.org. xml2vdr can convert this XML file into a "channels.conf" file suitable for use with the VDR application. In order to use the included "xml2vdr" utility, you should install the latest version of libxml (Version 2) from www.xmlsoft.org. I would recommend getting the very last ".tar.gz" source version and install using the standard ./configure make make install set of commands. If you are using dvbtune for DVB-T in Finland, you should replace the "make" command with "make FINLAND=1". or "make FINLAND2=1" (see the comments in the dvb_defaults.h file for details). Once you have installed libxml (if required), then you can compile dvbtune and xml2vdr by just typing "make" in the dvbtune directory. Usage ----- Just type "dvbtune" by itself for the full list of options. For simple tuning operations you can just use: ./dvbtune -f 12188000 -p h -s 27500 -v 163 -a 104 -t 32 to tune to a satellite transponder and set the video, audio and teletext PIDs. dvbtune also support DVB-T reception (currently for the UK only). In this case, you just need to specify the frequency: ./dvbtune -f 481833000 To get the DVB SI information for a multiplex, you can use the "-i" option. The output of dvbtune needs some addition lines before it is a valid XML file. e.g. use a script containing echo '' > test.xml echo '' >> test.xml ./dvbtune -f freq -s srate -p pol -i >> test.xml echo '' >> test.xml to dump the SI for a satellite transponder. This was done to allow you to write scripts to scan multiple transponders and write the output to the same XML file. See the "scripts" subdirectory for examples. Contributors ------------ Hilmar Linder - January 2002: Added Switch -n that adds a network interface and switch -m that monitors the reception quality. Changed the tuning code. Added command line parameters for spectral inversion. Changed code to allow L-Band frequencies with -f switch John Williams - March 2002. Added -D diseqc support, and made the 22kHz tone automatic again. Tomi Ollila - June 2002. Changes to FINLAND DVB-T tuning, and dvb_defaults.h suggestion. Copyright --------- (C) Dave Chapman 2001-2004 http://www.linuxstb.org 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. dvbtune-0.5/dvb_defaults.h0000644000076400017500000000564307511513432015535 0ustar davedave00000000000000/* dvb_defaults.h Provided by Tomi Ollila Copyright (C) Dave Chapman 2002 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 */ #ifndef _DVB_DEFAULTS_H #define _DVB_DEFAULTS_H /* DVB-S */ // With a diseqc system you may need different values per LNB. I hope // no-one ever asks for that :-) #define SLOF (11700*1000UL) #define LOF1 (9750*1000UL) #define LOF2 (10600*1000UL) /* DVB-T */ /* Either uncomment one of the following lines, or add it to your "make" command. e.g. make FINLAND=1 */ //#define UK //#define FINLAND //#define FINLAND2 /* UK defines are at the end, as a default option */ #ifdef FINLAND /* FINLAND settings 1 */ #define DVB_T_LOCATION "Suomessa" #define BANDWIDTH_DEFAULT BANDWIDTH_8_MHZ #define HP_CODERATE_DEFAULT FEC_2_3 #define CONSTELLATION_DEFAULT QAM_64 #define TRANSMISSION_MODE_DEFAULT TRANSMISSION_MODE_8K #define GUARD_INTERVAL_DEFAULT GUARD_INTERVAL_1_8 #define HIERARCHY_DEFAULT HIERARCHY_NONE #endif #ifdef FINLAND2 /* FINLAND settings 2 (someone verify there is such environment) */ #define DVB_T_LOCATION "Suomessa II" #define BANDWIDTH_DEFAULT BANDWIDTH_8_MHZ #define HP_CODERATE_DEFAULT FEC_1_2 #define CONSTELLATION_DEFAULT QAM_64 #define TRANSMISSION_MODE_DEFAULT TRANSMISSION_MODE_2K #define GUARD_INTERVAL_DEFAULT GUARD_INTERVAL_1_8 #define HIERARCHY_DEFAULT HIERARCHY_NONE #endif #if defined (UK) && defined (HP_CODERATE_DEFAULT) #error Multible countries defined #endif #ifndef DVB_T_LOCATION #ifndef UK #warning No DVB-T country defined in dvb_defaults.h #warning defaulting to UK #warning Ignore this if using Satellite or Cable #endif /* UNITED KINGDOM settings */ #define DVB_T_LOCATION "in United Kingdom" #define BANDWIDTH_DEFAULT BANDWIDTH_8_MHZ #define HP_CODERATE_DEFAULT FEC_2_3 #define CONSTELLATION_DEFAULT QAM_64 #define TRANSMISSION_MODE_DEFAULT TRANSMISSION_MODE_2K #define GUARD_INTERVAL_DEFAULT GUARD_INTERVAL_1_32 #define HIERARCHY_DEFAULT HIERARCHY_NONE #endif #if HIERARCHY_DEFAULT == HIERARCHY_NONE && !defined (LP_CODERATE_DEFAULT) #define LP_CODERATE_DEFAULT (0) /* unused if HIERARCHY_NONE */ #endif #endif dvbtune-0.5/dvbtune.c0000644000076400017500000012566310012450527014535 0ustar davedave00000000000000/* dvbtune - a program for tuning DVB TV and Radio channels. Initial transponders for "-x" option: Astra 28E: Astra 19E: 12670v - srate 22000 Hotbird 13E: 10911v - srate 27500 ?? Doesn't work! Thor etc 1W: 11247v - srate 24500 (Most channels!) Copyright (C) Dave Chapman 2001-2004 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 Added Switch -n that adds a network interface and switch -m that monitors the reception quality. Changed the tuning code Added command line parameters for spectral inversion. Changed code to allow L-Band frequencies with -f switch Copyright (C) Hilmar Linder 2002 */ // Linux includes: #include #include #include #include #include #include #include #include // DVB includes: #ifdef NEWSTRUCT #include #include #include #include #include #include #else #include #include #include #include #include #include #include #endif #include "tune.h" #define SECA_CA_SYSTEM 0x0100 #define VIACCESS_CA_SYSTEM 0x0500 #define IRDETO_CA_SYSTEM 0x0600 #define VIDEOGUARD_CA_SYSTEM 0x0900 #define BETA_CA_SYSTEM 0x1700 #define NAGRA_CA_SYSTEM 0x1800 #define CONAX_CA_SYSTEM 0x0b00 int fd_demuxv,fd_demuxa,fd_demuxtt,fd_demuxsi,fd_demuxrec,fd_demuxd; int pnr=-1; int apid=0; int vpid=0; int card=0; fe_spectral_inversion_t specInv = INVERSION_AUTO; int tone = -1; #ifdef NEWSTRUCT char* frontenddev[4]={"/dev/dvb/adapter0/frontend0","/dev/dvb/adapter1/frontend0","/dev/dvb/adapter2/frontend0","/dev/dvb/adapter3/frontend0"}; char* dvrdev[4]={"/dev/dvb/adapter0/dvr0","/dev/dvb/adapter1/dvr0","/dev/dvb/adapter2/dvr0","/dev/dvb/adapter3/dvr0"}; char* demuxdev[4]={"/dev/dvb/adapter0/demux0","/dev/dvb/adapter1/demux0","/dev/dvb/adapter2/demux0","/dev/dvb/adapter3/demux0"}; #else char* frontenddev[4]={"/dev/ost/frontend0","/dev/ost/frontend1","/dev/ost/frontend2","/dev/ost/frontend3"}; char* dvrdev[4]={"/dev/ost/dvr0","/dev/ost/dvr1","/dev/ost/dvr2","/dev/ost/dvr3"}; char* secdev[4]={"/dev/ost/sec0","/dev/ost/sec1","/dev/ost/sec2","/dev/ost/sec3"}; char* demuxdev[4]={"/dev/ost/demux0","/dev/ost/demux1","/dev/ost/demux2","/dev/ost/demux3"}; #endif typedef struct _transponder_t { int id; int onid; unsigned int freq; int srate; int pos; int we_flag; char pol; int mod; int scanned; struct _transponder_t* next; } transponder_t; transponder_t* transponders=NULL; int num_trans=0; transponder_t transponder; typedef struct _pat_t { int service_id; int pmt_pid; int scanned; struct _pat_t* next; } pat_t; pat_t* pats=NULL; /* Get the first unscanned transponder (or return NULL) */ transponder_t* get_unscanned() { transponder_t* t; t=transponders; while (t!=NULL) { if (t->scanned==0) { return(t); }; t=t->next; } return NULL; } char xmlify_result[10]; char* xmlify (char c) { switch(c) { case '&': strcpy(xmlify_result,"&"); break; case '<': strcpy(xmlify_result,"<"); break; case '>': strcpy(xmlify_result,">"); break; case '\"': strcpy(xmlify_result,"""); break; case 0: xmlify_result[0]=0; break; default: xmlify_result[0]=c; xmlify_result[1]=0; break; } return(xmlify_result); } void add_transponder(transponder_t transponder) { transponder_t* t; int found; if (transponders==NULL) { transponders=(transponder_t*)malloc(sizeof(transponder)); transponders->freq=transponder.freq; transponders->srate=transponder.srate; transponders->pol=transponder.pol; transponders->pos=transponder.pos; transponders->we_flag=transponder.we_flag; transponders->mod=transponder.mod; transponders->scanned=0; transponders->next=NULL; } else { t=transponders; found=0; while ((!found) && (t!=NULL)) { /* Some transponders appear with slightly different frequencies - ignore a new transponder if it is within 3MHz of another */ if ((abs(t->freq-transponder.freq)<=3000) && (t->pol==transponder.pol)) { found=1; } else { t=t->next; } } if (!found) { t=(transponder_t*)malloc(sizeof(transponder)); t->freq=transponder.freq; t->srate=transponder.srate; t->pol=transponder.pol; t->pos=transponder.pos; t->we_flag=transponder.we_flag; t->mod=transponder.mod; t->scanned=0; t->next=transponders; transponders=t; } } } void free_pat_list() { pat_t* t=pats; while (pats!=NULL) { t=pats->next; free(pats); pats=t; } } int get_pmt_pid(int service_id) { pat_t* t=pats; int found=0; while ((!found) && (t!=NULL)) { if (t->service_id==service_id) { found=1; } else { t=t->next; } } if (found) { return(t->pmt_pid); } else { return(0); } } void add_pat(pat_t pat) { pat_t* t; int found; if (pats==NULL) { pats=(pat_t*)malloc(sizeof(pat)); pats->service_id=pat.service_id; pats->pmt_pid=pat.pmt_pid; pats->scanned=0; pats->next=NULL; } else { t=pats; found=0; while ((!found) && (t!=NULL)) { if ((t->service_id==pat.service_id)) { found=1; } else { t=t->next; } } if (!found) { t=(pat_t*)malloc(sizeof(pat)); t->service_id=pat.service_id; t->pmt_pid=pat.pmt_pid; t->scanned=0; t->next=pats; pats=t; } } } void set_recpid(int fd, ushort ttpid) { struct dmx_pes_filter_params pesFilterParamsREC; if (ttpid==0 || ttpid==0xffff) { ioctl(fd, DMX_STOP, 0); return; } pesFilterParamsREC.pid = ttpid; pesFilterParamsREC.input = DMX_IN_FRONTEND; pesFilterParamsREC.output = DMX_OUT_TAP; #ifdef NEWSTRUCT pesFilterParamsREC.pes_type = DMX_PES_OTHER; #else pesFilterParamsREC.pesType = DMX_PES_OTHER; #endif pesFilterParamsREC.flags = DMX_IMMEDIATE_START; if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParamsREC) < 0) perror("set_recpid"); } void set_sipid(ushort ttpid) { struct dmx_pes_filter_params pesFilterParamsSI; if (ttpid==0 || ttpid==0xffff) { ioctl(fd_demuxsi, DMX_STOP, 0); return; } pesFilterParamsSI.pid = ttpid; pesFilterParamsSI.input = DMX_IN_FRONTEND; pesFilterParamsSI.output = DMX_OUT_TS_TAP; #ifdef NEWSTRUCT pesFilterParamsSI.pes_type = DMX_PES_OTHER; #else pesFilterParamsSI.pesType = DMX_PES_OTHER; #endif pesFilterParamsSI.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxsi, DMX_SET_PES_FILTER, &pesFilterParamsSI) < 0) perror("set_sipid"); } void set_ttpid(ushort ttpid) { struct dmx_pes_filter_params pesFilterParamsTT; if (ttpid==0 || ttpid==0xffff) { ioctl(fd_demuxtt, DMX_STOP, 0); return; } pesFilterParamsTT.pid = ttpid; pesFilterParamsTT.input = DMX_IN_FRONTEND; pesFilterParamsTT.output = DMX_OUT_DECODER; #ifdef NEWSTRUCT pesFilterParamsTT.pes_type = DMX_PES_TELETEXT; #else pesFilterParamsTT.pesType = DMX_PES_TELETEXT; #endif pesFilterParamsTT.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxtt, DMX_SET_PES_FILTER, &pesFilterParamsTT) < 0) perror("set_ttpid"); } void set_vpid(ushort vpid) { struct dmx_pes_filter_params pesFilterParamsV; if (vpid==0 || vpid==0xffff) { ioctl(fd_demuxv, DMX_STOP, 0); return; } pesFilterParamsV.pid = vpid; pesFilterParamsV.input = DMX_IN_FRONTEND; pesFilterParamsV.output = DMX_OUT_DECODER; #ifdef NEWSTRUCT pesFilterParamsV.pes_type = DMX_PES_VIDEO; #else pesFilterParamsV.pesType = DMX_PES_VIDEO; #endif pesFilterParamsV.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxv, DMX_SET_PES_FILTER, &pesFilterParamsV) < 0) perror("set_vpid"); } void set_apid(ushort apid) { struct dmx_pes_filter_params pesFilterParamsA; if (apid==0 || apid==0xffff) { ioctl(fd_demuxa, DMX_STOP, apid); return; } pesFilterParamsA.pid = apid; pesFilterParamsA.input = DMX_IN_FRONTEND; pesFilterParamsA.output = DMX_OUT_DECODER; #ifdef NEWSTRUCT pesFilterParamsA.pes_type = DMX_PES_AUDIO; #else pesFilterParamsA.pesType = DMX_PES_AUDIO; #endif pesFilterParamsA.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxa, DMX_SET_PES_FILTER, &pesFilterParamsA) < 0) perror("set_apid"); } void set_dpid(ushort dpid) { struct dmx_sct_filter_params sctFilterParams; if (dpid==0 || dpid==0xffff) { ioctl(fd_demuxd, DMX_STOP, dpid); return; } memset(&sctFilterParams.filter,0,sizeof(sctFilterParams.filter)); sctFilterParams.pid = dpid; //sctFilterParams.filter.filter[0] = 0x3e; //sctFilterParams.filter.mask[0] = 0xff; sctFilterParams.timeout = 0; sctFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(fd_demuxd, DMX_SET_FILTER, &sctFilterParams) < 0) perror("set_dpid"); } void set_ts_filter(int fd,uint16_t pid) { struct dmx_pes_filter_params pesFilterParams; pesFilterParams.pid = pid; pesFilterParams.input = DMX_IN_FRONTEND; pesFilterParams.output = DMX_OUT_TS_TAP; #ifdef NEWSTRUCT pesFilterParams.pes_type = DMX_PES_OTHER; #else pesFilterParams.pesType = DMX_PES_OTHER; #endif // A HACK TO DECODE STREAMS ON DVB-S CARD WHILST STREAMING // if (pid==255) pesFilterParams.pesType = DMX_PES_VIDEO; // if (pid==256) pesFilterParams.pesType = DMX_PES_AUDIO; pesFilterParams.flags = DMX_IMMEDIATE_START; if (ioctl(fd, DMX_SET_PES_FILTER, &pesFilterParams) < 0) { fprintf(stderr,"FILTER %i: ",pid); perror("DMX SET PES FILTER"); } } void parse_descriptors(int info_len,unsigned char *buf) { int i=0; int descriptor_tag,descriptor_length,j,k,pid,id; int service_type; char tmp[128]; unsigned int freq, pol, sr; while (i < info_len) { descriptor_tag=buf[i++]; descriptor_length=buf[i++]; // printf("Found descriptor: 0x%02x - length %02d\n",descriptor_tag,descriptor_length); while (descriptor_length > 0) { switch(descriptor_tag) { case 0x03: // audio_stream_descriptor printf("\n",buf[i]); i+=descriptor_length; descriptor_length=0; break; case 0x06: // data_stream_alignmentdescriptor printf("\n",buf[i]); i+=descriptor_length; descriptor_length=0; break; case 0x0a: // iso_639_language_descriptor for (j=0;j<((descriptor_length)/4);j++) { printf("\n",buf[i+3]); i+=4; descriptor_length-=4; } break; case 0x0b: // system_clock_descriptor printf("\n",buf[i],buf[i+1]); i+=descriptor_length; descriptor_length=0; break; case 0x09: // ca_descriptor k=((buf[i]<<8)|buf[i+1]); switch(k&0xff00) { case SECA_CA_SYSTEM: for (j=2; j\n",k,pid,id); } break; case VIACCESS_CA_SYSTEM: j = 4; while (j < descriptor_length) { if (buf[i+j]==0x14) { pid = ((buf[i+2] & 0x1f) << 8) | buf[i+3]; id = (buf[i+j+2] << 16) | (buf[i+j+3] << 8) | (buf[i+j+4] & 0xf0); printf("\n",k,pid,id); } j += 2+buf[i+j+1]; } break; case IRDETO_CA_SYSTEM: case BETA_CA_SYSTEM: pid = ((buf[i+2] & 0x1f) << 8) | buf[i+3]; printf("\n",k,pid); break; case NAGRA_CA_SYSTEM: pid = ((buf[i+2] & 0x1f) << 8) | buf[i+3]; printf("\n",k,pid); break; case CONAX_CA_SYSTEM: pid = ((buf[i+2] & 0x1f) << 8) | buf[i+3]; printf("\n",k,pid); break; case VIDEOGUARD_CA_SYSTEM: pid = ((buf[i+2] & 0x1f) << 8) | buf[i+3]; printf("\n",k,pid); break; default: pid = ((buf[i+2] & 0x1f) << 8) | buf[i+3]; printf("\n",k); break; } i+=descriptor_length; descriptor_length=0; break; case 0x40: // network_name // printf(""); j=descriptor_length; while(j > 0) { // printf("%c",buf[i++]); j--; } descriptor_length=0; // printf("\n"); break; case 0x41: // service_list // printf("\n",descriptor_length/3); while (descriptor_length > 0) { // printf("\n",(buf[i]<<8)|buf[i+1],buf[i+2]); i+=3; descriptor_length-=3; } // printf("\n"); break; case 0x43: // satellite_delivery_system freq=(unsigned int)(buf[i]<<24)|(buf[i+1]<<16)|(buf[i+2]<<8)|buf[i+3]; sprintf(tmp,"%x",freq); transponder.freq=atoi(tmp)*10; i+=4; transponder.pos=(buf[i]<<8)|buf[i+1]; i+=2; transponder.we_flag=(buf[i]&0x80)>>7; pol=(buf[i]&0x60)>>5; switch(pol) { case 0 : transponder.pol='H'; break; case 1 : transponder.pol='V'; break; case 2 : transponder.pol='L'; break; case 3 : transponder.pol='R'; break; } transponder.mod=buf[i]&0x1f; i++; sr=(unsigned int)(buf[i]<<24)|(buf[i+1]<<16)|(buf[i+2]<<8)|(buf[i+3]&0xf0); sr=(unsigned int)(sr >> 4); sprintf(tmp,"%x",sr); transponder.srate=atoi(tmp)*100; i+=4; descriptor_length=0; add_transponder(transponder); // printf("\n",transponder.freq,transponder.srate,transponder.pos,transponder.we_flag,transponder.pol,transponder.mod); break; case 0x48: // service_description service_type=buf[i++]; printf(" 0) { printf("%s",xmlify(buf[i++])); j--; } printf("\" service_name=\""); j=buf[i++]; descriptor_length-=(j+1); while(j > 0) { printf("%s",xmlify(buf[i])); i++; j--; } printf("\" />\n"); break; case 0x49: // country_availability: printf(">7); i++; j=descriptor_length-1; while (j > 0) { printf("%c",buf[i++]); j--; } printf("\" />\n"); descriptor_length=0; break; case 0x4c: printf("\n",(buf[i]<<8)|buf[i+1]); i+=descriptor_length; descriptor_length=0; break; case 0x52: // stream_identifier_descriptor printf("\n",buf[i]); i+=descriptor_length; descriptor_length=0; break; case 0x53: printf("\n",descriptor_length); for (j=0;j%04x\n",k); } i+=descriptor_length; descriptor_length=0; printf("\n"); break; case 0x56: j=0; printf("\n"); while (j < descriptor_length) { printf("\n",(buf[i+3]&0xf8)>>3,(k==0 ? 8 : k),buf[i+4]); i+=5; j+=5; } printf("\n"); descriptor_length=0; break; case 0x59: j=0; printf("\n"); while (j < descriptor_length) { printf("\n",buf[i+3],(buf[i+4]<<8)|buf[i+5],(buf[i+6]<<8)|buf[i+7]); i+=8; j+=8; } printf("\n"); descriptor_length=0; break; case 0x6a: printf("\n"); i+=descriptor_length; descriptor_length=0; break; case 0xc5: // canal_satellite_radio_descriptor /* This is guessed from the data */ printf("\n"); i+=descriptor_length; descriptor_length=0; break; default: printf("\n"); i+=descriptor_length; descriptor_length=0; break; } } } } void dump(char* fname, int len, char* buf) { FILE* f; f=fopen(fname,"w"); if (f) { fwrite(buf,1,len,f); fclose(f); } } int scan_nit(int x) { int fd_nit; int n,seclen; int i; struct pollfd ufd; unsigned char buf[4096]; struct dmx_sct_filter_params sctFilterParams; int info_len,network_id; if((fd_nit = open(demuxdev[card],O_RDWR|O_NONBLOCK)) < 0){ perror("fd_nit DEVICE: "); return -1; } sctFilterParams.pid=0x10; memset(&sctFilterParams.filter,0,sizeof(sctFilterParams.filter)); sctFilterParams.timeout = 0; sctFilterParams.flags = DMX_IMMEDIATE_START; sctFilterParams.filter.filter[0]=x; sctFilterParams.filter.mask[0]=0xff; if (ioctl(fd_nit,DMX_SET_FILTER,&sctFilterParams) < 0) { perror("NIT - DMX_SET_FILTER:"); close(fd_nit); return -1; } ufd.fd=fd_nit; ufd.events=POLLPRI; if (poll(&ufd,1,10000) < 0 ) { fprintf(stderr,"TIMEOUT on read from fd_nit\n"); close(fd_nit); return -1; } if (read(fd_nit,buf,3)==3) { seclen=((buf[1] & 0x0f) << 8) | (buf[2] & 0xff); n = read(fd_nit,buf+3,seclen); if (n==seclen) { seclen+=3; // dump("nit.dat",seclen,buf); // printf("\n"); network_id=(buf[3]<<8)|buf[4]; // printf("\n",network_id); info_len=((buf[8]&0x0f)<<8)|buf[9]; i=10; parse_descriptors(info_len,&buf[i]); i+=info_len; i+=2; while (i < (seclen-4)) { transponder.id=(buf[i]<<8)|buf[i+1]; i+=2; transponder.onid=(buf[i]<<8)|buf[i+1]; i+=2; // printf("\n",transponder.id,transponder.onid); info_len=((buf[i]&0x0f)<<8)|buf[i+1]; i+=2; parse_descriptors(info_len,&buf[i]); // printf("\n"); i+=info_len; } // printf("\n"); // printf("\n"); } else { fprintf(stderr,"Under-read bytes for NIT - wanted %d, got %d\n",seclen,n); } } else { fprintf(stderr,"Nothing to read from fd_nit\n"); } close(fd_nit); return(0); } void scan_pmt(int pid,int sid,int change) { int fd_pmt; int n,seclen; int i; unsigned char buf[4096]; struct dmx_sct_filter_params sctFilterParams; int service_id; int info_len,es_pid,stream_type; struct pollfd ufd; // printf("Scanning pmt: pid=%d, sid=%d\n",pid,sid); if (pid==0) { return; } if((fd_pmt = open(demuxdev[card],O_RDWR|O_NONBLOCK)) < 0){ perror("fd_pmt DEVICE: "); return; } sctFilterParams.pid=pid; memset(&sctFilterParams.filter,0,sizeof(sctFilterParams.filter)); sctFilterParams.timeout = 0; sctFilterParams.flags = DMX_IMMEDIATE_START; sctFilterParams.filter.filter[0]=0x02; sctFilterParams.filter.mask[0]=0xff; if (ioctl(fd_pmt,DMX_SET_FILTER,&sctFilterParams) < 0) { perror("PMT - DMX_SET_FILTER:"); close(fd_pmt); return; } ufd.fd=fd_pmt; ufd.events=POLLPRI; if (poll(&ufd,1,10000) < 0) { fprintf(stderr,"TIMEOUT reading from fd_pmt\n"); close(fd_pmt); return; } if (read(fd_pmt,buf,3)==3) { seclen=((buf[1] & 0x0f) << 8) | (buf[2] & 0xff); n = read(fd_pmt,buf+3,seclen); if (n==seclen) { seclen+=3; // printf("\n"); service_id=(buf[3]<<8)|buf[4]; // printf("\n",service_id,pid); if (sid != service_id) { close(fd_pmt); scan_pmt(pid, sid, change); return; } info_len=((buf[10]&0x0f)<<8)|buf[11]; i=12; parse_descriptors(info_len,&buf[i]); i+=info_len; while (i < (seclen-4)) { stream_type=buf[i++]; es_pid=((buf[i]&0x1f)<<8)|buf[i+1]; printf("\n",stream_type,es_pid); if (change) { if ((vpid==0) && ((stream_type==1) || (stream_type==2))) { vpid=es_pid; } if ((apid==0) && ((stream_type==3) || (stream_type==4))) { apid=es_pid; } } i+=2; info_len=((buf[i]&0x0f)<<8)|buf[i+1]; i+=2; parse_descriptors(info_len,&buf[i]); i+=info_len; printf("\n"); } // printf("\n"); // printf("\n"); } else { printf("Under-read bytes for PMT - wanted %d, got %d\n",seclen,n); } } else { fprintf(stderr,"Nothing to read from fd_pmt\n"); } close(fd_pmt); } void scan_pat() { int fd_pat; int n,seclen; int i; unsigned char buf[4096]; struct dmx_sct_filter_params sctFilterParams; struct pollfd ufd; pat_t pat; if((fd_pat = open(demuxdev[card],O_RDWR|O_NONBLOCK)) < 0){ perror("fd_pat DEVICE: "); return; } sctFilterParams.pid=0x0; memset(&sctFilterParams.filter,0,sizeof(sctFilterParams.filter)); sctFilterParams.timeout = 0; sctFilterParams.flags = DMX_IMMEDIATE_START; sctFilterParams.filter.filter[0]=0x0; sctFilterParams.filter.mask[0]=0xff; if (ioctl(fd_pat,DMX_SET_FILTER,&sctFilterParams) < 0) { perror("PAT - DMX_SET_FILTER:"); close(fd_pat); return; } ufd.fd=fd_pat; ufd.events=POLLPRI; if (poll(&ufd,1,10000) < 0) { fprintf(stderr,"TIMEOUT reading from fd_pat\n"); close(fd_pat); return; } if (read(fd_pat,buf,3)==3) { seclen=((buf[1] & 0x0f) << 8) | (buf[2] & 0xff); n = read(fd_pat,buf+3,seclen); if (n==seclen) { seclen+=3; // printf("Read %d bytes - Found %d services\n",seclen,(seclen-11)/4); // for (i=0;i\n"); i=8; while (i < seclen-4) { pat.service_id=(buf[i]<<8)|buf[i+1]; pat.pmt_pid=((buf[i+2]&0x1f)<<8)|buf[i+3]; add_pat(pat); /* if (service_id!=0) { scan_pmt(pmt_pid,service_id,(service_id==pnr)); } else { printf("\n\n",pmt_pid); } */ i+=4; } // printf("\n"); } else { printf("Under-read bytes for PAT - wanted %d, got %d\n",seclen,n); } } else { fprintf(stderr,"Nothing to read from fd_pat\n"); } close(fd_pat); } void scan_sdt() { int fd_sdt; int n,seclen; int i,k; int max_k; unsigned char buf[4096]; struct dmx_sct_filter_params sctFilterParams; int ca,service_id,loop_length; struct pollfd ufd; if((fd_sdt = open(demuxdev[card],O_RDWR|O_NONBLOCK)) < 0){ perror("fd_sdt DEVICE: "); return; } sctFilterParams.pid=0x11; memset(&sctFilterParams.filter,0,sizeof(sctFilterParams.filter)); sctFilterParams.timeout = 0; sctFilterParams.flags = DMX_IMMEDIATE_START; sctFilterParams.filter.filter[0]=0x42; sctFilterParams.filter.mask[0]=0xff; if (ioctl(fd_sdt,DMX_SET_FILTER,&sctFilterParams) < 0) { perror("SDT - DMX_SET_FILTER:"); close(fd_sdt); return; } max_k=1; // printf("\n"); for (k=0;k31) && (buf[j]<=127)) ? buf[j] : '.'); } printf("\n"); } } */ max_k=buf[7]+1; // last_sec_num - read this many (+1) sections i=11; while (i < (seclen-4)) { service_id=(buf[i]<<8)|buf[i+1]; i+=2; i++; // Skip a field ca=(buf[i]&0x10)>>4; loop_length=((buf[i]&0x0f)<<8)|buf[i+1]; printf("\n",service_id,ca); i+=2; parse_descriptors(loop_length,&buf[i]); i+=loop_length; scan_pmt(get_pmt_pid(service_id),service_id,(service_id==pnr)); printf("\n"); } } else { printf("Under-read bytes for SDT - wanted %d, got %d\n",seclen,n); } } else { fprintf(stderr,"Nothing to read from fd_sdt\n"); } } // printf("\n"); close(fd_sdt); } int FEReadBER(int fd, uint32_t *ber) { int ans; if ( (ans = ioctl(fd,FE_READ_BER, ber) < 0)){ perror("FE READ_BER: "); return -1; } 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; } 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; } return 0; } #if 0 int FEReadAFC(int fd, int32_t *snr) { int ans; if ( (ans = ioctl(fd,FE_READ_AFC, snr) < 0)){ perror("FE READ_AFC: "); return -1; } return 0; } #endif 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; } return 0; } int main(int argc, char **argv) { int fd_frontend=0; int fd_sec=0; int fd_dvr=0; int do_info=0; int do_scan=0; int do_monitor=0; unsigned int freq=0; char pol=0; unsigned int srate=0; unsigned int diseqc = 0; int ttpid=0; int dpid=0; fe_modulation_t modulation=CONSTELLATION_DEFAULT; fe_transmit_mode_t TransmissionMode=TRANSMISSION_MODE_DEFAULT; fe_bandwidth_t bandWidth=BANDWIDTH_DEFAULT; fe_guard_interval_t guardInterval=GUARD_INTERVAL_DEFAULT; fe_code_rate_t HP_CodeRate=HP_CODERATE_DEFAULT; int count; transponder_t * t; int i; if (argc==1) { fprintf(stderr,"Usage: dvbtune [OPTIONS]\n\n"); fprintf(stderr,"Standard options:\n\n"); fprintf(stderr,"-f freq absolute Frequency (DVB-S in Hz or DVB-T in Hz)\n"); fprintf(stderr," or L-band Frequency (DVB-S in Hz or DVB-T in Hz)\n"); fprintf(stderr,"-p [H,V] Polarity (DVB-S only)\n"); fprintf(stderr,"-s N Symbol rate (DVB-S or DVB-C)\n"); fprintf(stderr,"-v vpid Decode video PID (full cards only)\n"); fprintf(stderr,"-a apid Decode audio PID (full cards only)\n"); fprintf(stderr,"-t ttpid Decode teletext PID (full cards only)\n"); fprintf(stderr,"-pnr N Tune to Program Number (aka service) N\n\n"); fprintf(stderr,"-i Dump SI information as XML\n"); fprintf(stderr,"\nAdvanced tuning options:\n\n"); fprintf(stderr,"-c [0-3] Use DVB card #[0-3]\n"); fprintf(stderr,"-tone [0|1] 0=22kHz off, 1=22kHz on\n"); fprintf(stderr,"-I [0|1|2] 0=Spectrum Inversion off, 1=Spectrum Inversion on, 2=auto\n"); fprintf(stderr,"-D [0-4] DiSEqC command (0=none)\n\n"); fprintf(stderr,"-qam X DVB-T modulation - 16%s, 32%s, 64%s, 128%s or 256%s\n",(CONSTELLATION_DEFAULT==QAM_16 ? " (default)" : ""),(CONSTELLATION_DEFAULT==QAM_32 ? " (default)" : ""),(CONSTELLATION_DEFAULT==QAM_64 ? " (default)" : ""),(CONSTELLATION_DEFAULT==QAM_128 ? " (default)" : ""),(CONSTELLATION_DEFAULT==QAM_256 ? " (default)" : "")); fprintf(stderr,"-gi N DVB-T guard interval 1_N (N=32%s, 16%s, 8%s or 4%s)\n",(GUARD_INTERVAL_DEFAULT==GUARD_INTERVAL_1_32 ? " (default)" : ""),(GUARD_INTERVAL_DEFAULT==GUARD_INTERVAL_1_16 ? " (default)" : ""),(GUARD_INTERVAL_DEFAULT==GUARD_INTERVAL_1_8 ? " (default)" : ""),(GUARD_INTERVAL_DEFAULT==GUARD_INTERVAL_1_4 ? " (default)" : "")); fprintf(stderr,"-cr N DVB-T code rate. N=AUTO%s, 1_2%s, 2_3%s, 3_4%s, 5_6%s, 7_8%s\n",(HP_CODERATE_DEFAULT==FEC_AUTO ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_1_2 ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_2_3 ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_3_4 ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_5_6 ? " (default)" : ""),(HP_CODERATE_DEFAULT==FEC_7_8 ? " (default)" : "")); fprintf(stderr,"-bw N DVB-T bandwidth (Mhz) - N=6%s, 7%s or 8%s\n",(BANDWIDTH_DEFAULT==BANDWIDTH_6_MHZ ? " (default)" : ""),(BANDWIDTH_DEFAULT==BANDWIDTH_7_MHZ ? " (default)" : ""),(BANDWIDTH_DEFAULT==BANDWIDTH_8_MHZ ? " (default)" : "")); fprintf(stderr,"-tm N DVB-T transmission mode - N=2%s or 8%s\n",(TRANSMISSION_MODE_DEFAULT==TRANSMISSION_MODE_2K ? " (default)" : ""),(TRANSMISSION_MODE_DEFAULT==TRANSMISSION_MODE_8K ? " (default)" : "")); fprintf(stderr,"-x Attempt to auto-find other transponders (experimental - DVB-S only)\n"); fprintf(stderr,"-m Monitor the reception quality\n"); fprintf(stderr,"-n dpid Add network interface and receive MPE on PID dpid\n"); fprintf(stderr,"\n"); return(-1); } else { count=0; for (i=1;i 3)) { fprintf(stderr,"card must be between 0 and 3\n"); exit(-1); } } else if (strcmp(argv[i],"-x")==0) { // do_scan=1; } else if (strcmp(argv[i],"-v")==0) { i++; vpid=atoi(argv[i]); } else if (strcmp(argv[i],"-pnr")==0) { i++; pnr=atoi(argv[i]); do_info=1; } else if (strcmp(argv[i],"-a")==0) { i++; apid=atoi(argv[i]); } else if (strcmp(argv[i],"-t")==0) { i++; ttpid=atoi(argv[i]); } else if (strcmp(argv[i],"-p")==0) { i++; if (argv[i][1]==0) { if (tolower(argv[i][0])=='v') { pol='V'; } else if (tolower(argv[i][0])=='h') { pol='H'; } else if (tolower(argv[i][0])=='l') { pol='L'; } else if (tolower(argv[i][0])=='r') { pol='R'; } } } else if (strcmp(argv[i],"-s")==0) { i++; srate=atoi(argv[i])*1000UL; } else if (strcmp(argv[i],"-qam")==0) { i++; switch(atoi(argv[i])) { case 16: modulation=QAM_16; break; case 32: modulation=QAM_32; break; case 64: modulation=QAM_64; break; case 128: modulation=QAM_128; break; case 256: modulation=QAM_256; break; default: fprintf(stderr,"Invalid QAM rate: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-gi")==0) { i++; switch(atoi(argv[i])) { case 32: guardInterval=GUARD_INTERVAL_1_32; break; case 16: guardInterval=GUARD_INTERVAL_1_16; break; case 8: guardInterval=GUARD_INTERVAL_1_8; break; case 4: guardInterval=GUARD_INTERVAL_1_4; break; default: fprintf(stderr,"Invalid Guard Interval: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-tm")==0) { i++; switch(atoi(argv[i])) { case 8: TransmissionMode=TRANSMISSION_MODE_8K; break; case 2: TransmissionMode=TRANSMISSION_MODE_2K; break; default: fprintf(stderr,"Invalid Transmission Mode: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-bw")==0) { i++; switch(atoi(argv[i])) { case 8: bandWidth=BANDWIDTH_8_MHZ; break; case 7: bandWidth=BANDWIDTH_7_MHZ; break; case 6: bandWidth=BANDWIDTH_6_MHZ; break; default: fprintf(stderr,"Invalid DVB-T bandwidth: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-cr")==0) { i++; if (!strcmp(argv[i],"AUTO")) { HP_CodeRate=FEC_AUTO; } else if (!strcmp(argv[i],"1_2")) { HP_CodeRate=FEC_1_2; } else if (!strcmp(argv[i],"2_3")) { HP_CodeRate=FEC_2_3; } else if (!strcmp(argv[i],"3_4")) { HP_CodeRate=FEC_3_4; } else if (!strcmp(argv[i],"5_6")) { HP_CodeRate=FEC_5_6; } else if (!strcmp(argv[i],"7_8")) { HP_CodeRate=FEC_7_8; } else { fprintf(stderr,"Invalid Code Rate: %s\n",argv[i]); exit(0); } } else if (strcmp(argv[i],"-D")==0) { i++; diseqc=atoi(argv[i]); if (diseqc > 4) { fprintf(stderr,"DiSEqC must be between 0 and 4\n"); exit(-1); } } else if (strcmp(argv[i],"-tone")==0) { i++; if (atoi(argv[i])==0) tone = SEC_TONE_OFF; else tone = SEC_TONE_ON; } else if (strcmp(argv[i],"-I")==0) { i++; if (atoi(argv[i])==0) specInv = INVERSION_OFF; else if (atoi(argv[i])==1) specInv = INVERSION_ON; else specInv = INVERSION_AUTO; } } } #if 0 if (!((freq > 100000000) || ((freq > 0) && (pol!=0) && (srate!=0)))) { fprintf(stderr,"Invalid parameters\n"); exit(-1); } #endif if((fd_dvr = open(dvrdev[card],O_RDONLY|O_NONBLOCK)) < 0){ fprintf(stderr,"FD %d: ",i); perror("fd_dvr DEMUX DEVICE: "); return -1; } if((fd_frontend = open(frontenddev[card],O_RDWR)) < 0){ fprintf(stderr,"frontend: %d",i); perror("FRONTEND DEVICE: "); return -1; } #ifndef NEWSTRUCT /* Only open sec for DVB-S tuning */ if (freq<100000000) { if((fd_sec = open(secdev[card],O_RDWR)) < 0) { fprintf(stderr,"FD %i: ",i); perror("SEC DEVICE (warning) "); } } #endif if((fd_demuxrec = open(demuxdev[card],O_RDWR|O_NONBLOCK)) < 0){ fprintf(stderr,"FD %i: ",i); perror("DEMUX DEVICE: "); return -1; } if((fd_demuxv = open(demuxdev[card],O_RDWR)) < 0){ fprintf(stderr,"FD %i: ",i); perror("DEMUX DEVICE: "); return -1; } if((fd_demuxa = open(demuxdev[card],O_RDWR)) < 0){ fprintf(stderr,"FD %i: ",i); perror("DEMUX DEVICE: "); return -1; } if((fd_demuxtt = open(demuxdev[card],O_RDWR)) < 0){ fprintf(stderr,"FD %i: ",i); perror("DEMUX DEVICE: "); return -1; } if((fd_demuxd = open(demuxdev[card],O_RDWR)) < 0){ fprintf(stderr,"FD %i: ",i); perror("DEMUX DEVICE: "); return -1; } if((fd_demuxsi = open(demuxdev[card],O_RDWR|O_NONBLOCK)) < 0){ fprintf(stderr,"FD %i: ",i); perror("DEMUX DEVICE: "); return -1; } if (freq > 0) { /* Stop the hardware filters */ set_apid(0); set_vpid(0); set_ttpid(0); if (tune_it(fd_frontend,fd_sec,freq,srate,pol,tone,specInv,diseqc,modulation,HP_CodeRate,TransmissionMode,guardInterval,bandWidth) < 0) { return -1; } } if (do_scan) { printf("\n\n"); scan_nit(0x40); /* Get initial list of transponders */ scan_nit(0x41); /* Get initial list of transponders */ while ((t=get_unscanned(transponders))!=NULL) { free_pat_list(); fprintf(stderr,"Scanning %d%c %d\n",t->freq,t->pol,t->srate); tune_it(fd_frontend,fd_sec,t->freq,t->srate,t->pol,tone,specInv,0,modulation,HP_CodeRate,TransmissionMode,guardInterval,bandWidth); printf("\n",t->id,t->onid,t->freq,t->srate,t->pos,t->we_flag,t->pol,t->mod); t->scanned=1; scan_pat(); scan_sdt(); printf("\n"); scan_nit(0x40); /* See if there are any new transponders */ scan_nit(0x41); /* See if there are any new transponders */ } printf("\n"); } if (do_info) { if (pol!=0) { printf("\n",freq,srate,pol); } else { if (srate!=0) { printf("\n",freq,srate); } else { if (freq<1000000) freq*=1000UL; printf("\n",freq); } } scan_pat(); scan_sdt(); // scan_nit(0x40); printf("\n"); } if ((vpid!=0) || (apid!=0) || (ttpid!=0)) { set_vpid(vpid); set_apid(apid); set_ttpid(ttpid); fprintf(stderr,"A/V/TT Filters set\n"); } if (dpid > 0) { char devnamen[80]; int dev, fdn; struct dvb_net_if netif; dev = card; netif.pid = dpid; netif.if_num = 0; // always choosen the next free number #ifdef NEWSTRUCT sprintf(devnamen,"/dev/dvb/adapter%d/net0",dev); #else sprintf(devnamen,"/dev/ost/net%d",dev); #endif //printf("Trying to open %s\n",devnamen); if((fdn = open(devnamen,O_RDWR|O_NONBLOCK)) < 0) { fprintf(stderr, "Failed to open DVB NET DEVICE"); close(fd_frontend); if (fd_sec) close(fd_sec); } else { // Add the network interface ioctl( fdn,NET_ADD_IF,&netif); close (fdn); printf("Successfully opened network device, please configure the dvb interface\n"); } } if (do_monitor) { int32_t strength, ber, snr, uncorr; fe_status_t festatus; if((fd_frontend = open(frontenddev[card],O_RDONLY)) < 0){ fprintf(stderr,"frontend: %d",i); perror("FRONTEND DEVICE: "); return -1; } // Check the signal strength and the BER while (1) { festatus = 0; strength = 0; ber = 0; snr = 0; uncorr = 0; FEReadBER(fd_frontend, &ber); FEReadSignalStrength(fd_frontend, &strength); FEReadSNR(fd_frontend, &snr); FEReadUncorrectedBlocks(fd_frontend, &uncorr); ioctl(fd_frontend,FE_READ_STATUS,&festatus); fprintf(stderr,"Signal=%d, Verror=%d, SNR=%ddB, BlockErrors=%d, (", strength, ber, snr, uncorr); #ifndef NEWSTRUCT if (festatus & FE_HAS_POWER) fprintf(stderr,"P|"); if (festatus & FE_SPECTRUM_INV) fprintf(stderr,"I|"); #endif if (festatus & FE_HAS_SIGNAL) fprintf(stderr,"S|"); if (festatus & FE_HAS_LOCK) fprintf(stderr,"L|"); if (festatus & FE_HAS_CARRIER) fprintf(stderr,"C|"); if (festatus & FE_HAS_VITERBI) fprintf(stderr,"V|"); if (festatus & FE_HAS_SYNC) fprintf(stderr,"SY|"); fprintf(stderr,")\n"); sleep(1); } } close(fd_frontend); if (fd_sec) close(fd_sec); return(0); } dvbtune-0.5/tune.c0000644000076400017500000004266610010717004014034 0ustar davedave00000000000000/* dvbtune - tune.c Copyright (C) Dave Chapman 2001,2002 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 #include #include #include #include #include #include #include #include #ifdef NEWSTRUCT #include #include #else #include #include #include #endif #include "tune.h" #ifndef NEWSTRUCT int OSTSelftest(int fd) { int ans; if ( (ans = ioctl(fd,FE_SELFTEST,0) < 0)){ perror("FE SELF TEST: "); return -1; } return 0; } int OSTSetPowerState(int fd, uint32_t state) { int ans; if ( (ans = ioctl(fd,FE_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,FE_GET_POWER_STATE,state) < 0)){ perror("OST GET POWER STATE: "); return -1; } switch(*state){ case FE_POWER_ON: fprintf(stderr,"POWER ON (%d)\n",*state); break; case FE_POWER_STANDBY: fprintf(stderr,"POWER STANDBY (%d)\n",*state); break; case FE_POWER_SUSPEND: fprintf(stderr,"POWER SUSPEND (%d)\n",*state); break; case FE_POWER_OFF: fprintf(stderr,"POWER OFF (%d)\n",*state); break; default: fprintf(stderr,"unknown (%d)\n",*state); break; } return 0; } int SecGetStatus (int fd, struct secStatus *state) { int ans; if ( (ans = ioctl(fd,SEC_GET_STATUS, state) < 0)){ perror("SEC GET STATUS: "); return -1; } switch (state->busMode){ case SEC_BUS_IDLE: fprintf(stderr,"SEC BUS MODE: IDLE (%d)\n",state->busMode); break; case SEC_BUS_BUSY: fprintf(stderr,"SEC BUS MODE: BUSY (%d)\n",state->busMode); break; case SEC_BUS_OFF: fprintf(stderr,"SEC BUS MODE: OFF (%d)\n",state->busMode); break; case SEC_BUS_OVERLOAD: fprintf(stderr,"SEC BUS MODE: OVERLOAD (%d)\n",state->busMode); break; default: fprintf(stderr,"SEC BUS MODE: unknown (%d)\n",state->busMode); break; } switch (state->selVolt){ case SEC_VOLTAGE_OFF: fprintf(stderr,"SEC VOLTAGE: OFF (%d)\n",state->selVolt); break; case SEC_VOLTAGE_LT: fprintf(stderr,"SEC VOLTAGE: LT (%d)\n",state->selVolt); break; case SEC_VOLTAGE_13: fprintf(stderr,"SEC VOLTAGE: 13 (%d)\n",state->selVolt); break; case SEC_VOLTAGE_13_5: fprintf(stderr,"SEC VOLTAGE: 13.5 (%d)\n",state->selVolt); break; case SEC_VOLTAGE_18: fprintf(stderr,"SEC VOLTAGE: 18 (%d)\n",state->selVolt); break; case SEC_VOLTAGE_18_5: fprintf(stderr,"SEC VOLTAGE: 18.5 (%d)\n",state->selVolt); break; default: fprintf(stderr,"SEC VOLTAGE: unknown (%d)\n",state->selVolt); break; } fprintf(stderr,"SEC CONT TONE: %s\n", (state->contTone == SEC_TONE_ON ? "ON" : "OFF")); return 0; } #endif void print_status(FILE* fd,fe_status_t festatus) { fprintf(fd,"FE_STATUS:"); if (festatus & FE_HAS_SIGNAL) fprintf(fd," FE_HAS_SIGNAL"); #ifdef NEWSTRUCT if (festatus & FE_TIMEDOUT) fprintf(fd," FE_TIMEDOUT"); #else if (festatus & FE_HAS_POWER) fprintf(fd," FE_HAS_POWER"); if (festatus & FE_SPECTRUM_INV) fprintf(fd," FE_SPECTRUM_INV"); if (festatus & FE_TUNER_HAS_LOCK) fprintf(fd," FE_TUNER_HAS_LOCK"); #endif if (festatus & FE_HAS_LOCK) fprintf(fd," FE_HAS_LOCK"); if (festatus & FE_HAS_CARRIER) fprintf(fd," FE_HAS_CARRIER"); if (festatus & FE_HAS_VITERBI) fprintf(fd," FE_HAS_VITERBI"); if (festatus & FE_HAS_SYNC) fprintf(fd," FE_HAS_SYNC"); fprintf(fd,"\n"); } #ifdef NEWSTRUCT 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) { ioctl(fd, FE_SET_TONE, SEC_TONE_OFF); ioctl(fd, FE_SET_VOLTAGE, v); usleep(15 * 1000); ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &cmd->cmd); usleep(cmd->wait * 1000); usleep(15 * 1000); ioctl(fd, FE_DISEQC_SEND_BURST, b); usleep(15 * 1000); ioctl(fd, FE_SET_TONE, t); } /* digital satellite equipment control, * specification is available from http://www.eutelsat.com/ */ static int do_diseqc(int secfd, int sat_no, int pol, int hi_lo) { 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_lo ? 1 : 0) | (pol ? 0 : 2)); diseqc_send_msg(secfd, pol, &cmd, hi_lo, (sat_no / 4) % 2 ? SEC_MINI_B : SEC_MINI_A); return 1; } int check_status(int fd_frontend,struct dvb_frontend_parameters* feparams,int tone) { int32_t strength; fe_status_t festatus; struct dvb_frontend_event event; struct dvb_frontend_info fe_info; struct pollfd pfd[1]; int status; if (ioctl(fd_frontend,FE_SET_FRONTEND,feparams) < 0) { perror("ERROR tuning channel\n"); return -1; } pfd[0].fd = fd_frontend; pfd[0].events = POLLIN; event.status=0; while (((event.status & FE_TIMEDOUT)==0) && ((event.status & FE_HAS_LOCK)==0)) { fprintf(stderr,"polling....\n"); if (poll(pfd,1,10000)){ if (pfd[0].revents & POLLIN){ fprintf(stderr,"Getting frontend event\n"); if ((status = ioctl(fd_frontend, FE_GET_EVENT, &event)) < 0){ if (errno != EOVERFLOW) { perror("FE_GET_EVENT"); fprintf(stderr,"status = %d\n", status); fprintf(stderr,"errno = %d\n", errno); return -1; } else fprintf(stderr,"Overflow error, trying again (status = %d, errno = %d)", status, errno); } } print_status(stderr,event.status); } } if (event.status & FE_HAS_LOCK) { switch(fe_info.type) { case FE_OFDM: fprintf(stderr,"Event: Frequency: %d\n",event.parameters.frequency); break; case FE_QPSK: fprintf(stderr,"Event: Frequency: %d\n",(unsigned int)((event.parameters.frequency)+(tone==SEC_TONE_OFF ? LOF1 : LOF2))); fprintf(stderr," SymbolRate: %d\n",event.parameters.u.qpsk.symbol_rate); fprintf(stderr," FEC_inner: %d\n",event.parameters.u.qpsk.fec_inner); fprintf(stderr,"\n"); break; case FE_QAM: fprintf(stderr,"Event: Frequency: %d\n",event.parameters.frequency); fprintf(stderr," SymbolRate: %d\n",event.parameters.u.qpsk.symbol_rate); fprintf(stderr," FEC_inner: %d\n",event.parameters.u.qpsk.fec_inner); break; default: break; } strength=0; ioctl(fd_frontend,FE_READ_BER,&strength); fprintf(stderr,"Bit error rate: %d\n",strength); strength=0; ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength); fprintf(stderr,"Signal strength: %d\n",strength); strength=0; ioctl(fd_frontend,FE_READ_SNR,&strength); fprintf(stderr,"SNR: %d\n",strength); festatus=0; ioctl(fd_frontend,FE_READ_STATUS,&festatus); print_status(stderr,festatus); } else { fprintf(stderr,"Not able to lock to the signal on the given frequency\n"); return -1; } return 0; } #else int check_status(int fd_frontend,FrontendParameters* feparams,int tone) { int i,res; int32_t strength; fe_status_t festatus; FrontendEvent event; FrontendInfo fe_info; struct pollfd pfd[1]; i = 0; res = -1; while ((i < 3) && (res < 0)) { if (ioctl(fd_frontend,FE_SET_FRONTEND,feparams) < 0) { perror("ERROR tuning channel\n"); return -1; } pfd[0].fd = fd_frontend; pfd[0].events = POLLIN; if (poll(pfd,1,10000)){ if (pfd[0].revents & POLLIN){ fprintf(stderr,"Getting frontend event\n"); if ( ioctl(fd_frontend, FE_GET_EVENT, &event) < 0) { perror("FE_GET_EVENT"); return -1; } fprintf(stderr,"Received "); switch(event.type){ case FE_UNEXPECTED_EV: fprintf(stderr,"unexpected event\n"); res = -1; break; case FE_FAILURE_EV: fprintf(stderr,"failure event\n"); res = -1; break; case FE_COMPLETION_EV: fprintf(stderr,"completion event\n"); res = 0; break; } } i++; } } if (res > 0) switch (event.type) { case FE_UNEXPECTED_EV: fprintf(stderr,"FE_UNEXPECTED_EV\n"); break; case FE_COMPLETION_EV: fprintf(stderr,"FE_COMPLETION_EV\n"); break; case FE_FAILURE_EV: fprintf(stderr,"FE_FAILURE_EV\n"); break; } if (event.type == FE_COMPLETION_EV) { switch(fe_info.type) { case FE_OFDM: fprintf(stderr,"Event: Frequency: %d\n",event.u.completionEvent.Frequency); break; case FE_QPSK: fprintf(stderr,"Event: Frequency: %d\n",(unsigned int)((event.u.completionEvent.Frequency)+(tone==SEC_TONE_OFF ? LOF1 : LOF2))); fprintf(stderr," SymbolRate: %d\n",event.u.completionEvent.u.qpsk.SymbolRate); fprintf(stderr," FEC_inner: %d\n",event.u.completionEvent.u.qpsk.FEC_inner); fprintf(stderr,"\n"); break; case FE_QAM: fprintf(stderr,"Event: Frequency: %d\n",event.u.completionEvent.Frequency); fprintf(stderr," SymbolRate: %d\n",event.u.completionEvent.u.qpsk.SymbolRate); fprintf(stderr," FEC_inner: %d\n",event.u.completionEvent.u.qpsk.FEC_inner); break; default: break; } strength=0; ioctl(fd_frontend,FE_READ_BER,&strength); fprintf(stderr,"Bit error rate: %d\n",strength); strength=0; ioctl(fd_frontend,FE_READ_SIGNAL_STRENGTH,&strength); fprintf(stderr,"Signal strength: %d\n",strength); strength=0; ioctl(fd_frontend,FE_READ_SNR,&strength); fprintf(stderr,"SNR: %d\n",strength); festatus=0; ioctl(fd_frontend,FE_READ_STATUS,&festatus); fprintf(stderr,"FE_STATUS:"); if (festatus & FE_HAS_POWER) fprintf(stderr," FE_HAS_POWER"); if (festatus & FE_HAS_SIGNAL) fprintf(stderr," FE_HAS_SIGNAL"); if (festatus & FE_SPECTRUM_INV) fprintf(stderr," FE_SPECTRUM_INV"); if (festatus & FE_HAS_LOCK) fprintf(stderr," FE_HAS_LOCK"); if (festatus & FE_HAS_CARRIER) fprintf(stderr," FE_HAS_CARRIER"); if (festatus & FE_HAS_VITERBI) fprintf(stderr," FE_HAS_VITERBI"); if (festatus & FE_HAS_SYNC) fprintf(stderr," FE_HAS_SYNC"); if (festatus & FE_TUNER_HAS_LOCK) fprintf(stderr," FE_TUNER_HAS_LOCK"); fprintf(stderr,"\n"); } else { fprintf(stderr,"Not able to lock to the signal on the given frequency\n"); return -1; } return 0; } #endif int tune_it(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned int diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth) { int res; #ifdef NEWSTRUCT struct dvb_frontend_parameters feparams; struct dvb_frontend_info fe_info; fe_sec_voltage_t voltage; #else FrontendParameters feparams; FrontendInfo fe_info; secVoltage voltage; struct secStatus sec_state; #endif /* discard stale frontend events */ /* pfd[0].fd = fd_frontend; pfd[0].events = POLLIN; if (poll(pfd,1,500)){ if (pfd[0].revents & POLLIN){ while (1) { if (ioctl (fd_frontend, FE_GET_EVENT, &event) == -1) { break; } } } } */ if ( (res = ioctl(fd_frontend,FE_GET_INFO, &fe_info) < 0)){ perror("FE_GET_INFO: "); return -1; } // OSTSelftest(fd_frontend); // OSTSetPowerState(fd_frontend, FE_POWER_ON); // OSTGetPowerState(fd_frontend, &festatus); #ifdef NEWSTRUCT fprintf(stderr,"Using DVB card \"%s\"\n",fe_info.name); #endif switch(fe_info.type) { case FE_OFDM: #ifdef NEWSTRUCT if (freq < 1000000) freq*=1000UL; feparams.frequency=freq; feparams.inversion=INVERSION_OFF; feparams.u.ofdm.bandwidth=bandwidth; feparams.u.ofdm.code_rate_HP=HP_CodeRate; feparams.u.ofdm.code_rate_LP=LP_CODERATE_DEFAULT; feparams.u.ofdm.constellation=modulation; feparams.u.ofdm.transmission_mode=TransmissionMode; feparams.u.ofdm.guard_interval=guardInterval; feparams.u.ofdm.hierarchy_information=HIERARCHY_DEFAULT; #else if (freq < 1000000) freq*=1000UL; feparams.Frequency=freq; feparams.Inversion=INVERSION_OFF; feparams.u.ofdm.bandWidth=bandwidth; feparams.u.ofdm.HP_CodeRate=HP_CodeRate; feparams.u.ofdm.LP_CodeRate=LP_CODERATE_DEFAULT; feparams.u.ofdm.Constellation=modulation; feparams.u.ofdm.TransmissionMode=TransmissionMode; feparams.u.ofdm.guardInterval=guardInterval; feparams.u.ofdm.HierarchyInformation=HIERARCHY_DEFAULT; #endif fprintf(stderr,"tuning DVB-T (%s) to %d Hz\n",DVB_T_LOCATION,freq); break; case FE_QPSK: #ifdef NEWSTRUCT fprintf(stderr,"tuning DVB-S to L-Band:%d, Pol:%c Srate=%d, 22kHz=%s\n",feparams.frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off"); #else fprintf(stderr,"tuning DVB-S to L-Band:%d, Pol:%c Srate=%d, 22kHz=%s\n",feparams.Frequency,pol,srate,tone == SEC_TONE_ON ? "on" : "off"); #endif if ((pol=='h') || (pol=='H')) { voltage = SEC_VOLTAGE_18; } else { voltage = SEC_VOLTAGE_13; } #ifdef NEWSTRUCT if (diseqc==0) if (ioctl(fd_frontend,FE_SET_VOLTAGE,voltage) < 0) { #else if (ioctl(fd_sec,SEC_SET_VOLTAGE,voltage) < 0) { #endif perror("ERROR setting voltage\n"); } if (freq > 2200000) { // this must be an absolute frequency if (freq < SLOF) { #ifdef NEWSTRUCT feparams.frequency=(freq-LOF1); #else feparams.Frequency=(freq-LOF1); #endif if (tone < 0) tone = SEC_TONE_OFF; } else { #ifdef NEWSTRUCT feparams.frequency=(freq-LOF2); #else feparams.Frequency=(freq-LOF2); #endif if (tone < 0) tone = SEC_TONE_ON; } } else { // this is an L-Band frequency #ifdef NEWSTRUCT feparams.frequency=freq; #else feparams.Frequency=freq; #endif } #ifdef NEWSTRUCT feparams.inversion=specInv; feparams.u.qpsk.symbol_rate=srate; feparams.u.qpsk.fec_inner=FEC_AUTO; #else feparams.Inversion=specInv; feparams.u.qpsk.SymbolRate=srate; feparams.u.qpsk.FEC_inner=FEC_AUTO; #endif #ifdef NEWSTRUCT if (diseqc==0) { if (ioctl(fd_frontend,FE_SET_TONE,tone) < 0) { perror("ERROR setting tone\n"); } } #else if (ioctl(fd_sec,SEC_SET_TONE,tone) < 0) { perror("ERROR setting tone\n"); } #endif #ifdef NEWSTRUCT if (diseqc > 0) { do_diseqc(fd_frontend, diseqc-1,voltage,tone); sleep(1); } #else if (diseqc > 0) { struct secCommand scmd; struct secCmdSequence scmds; scmds.continuousTone = tone; scmds.voltage = voltage; /* scmds.miniCommand = toneBurst ? SEC_MINI_B : SEC_MINI_A; */ scmds.miniCommand = SEC_MINI_NONE; scmd.type = 0; scmds.numCommands = 1; scmds.commands = &scmd; scmd.u.diseqc.addr = 0x10; scmd.u.diseqc.cmd = 0x38; scmd.u.diseqc.numParams = 1; scmd.u.diseqc.params[0] = 0xf0 | (((diseqc - 1) << 2) & 0x0c) | (voltage==SEC_VOLTAGE_18 ? 0x02 : 0) | (tone==SEC_TONE_ON ? 0x01 : 0); if (ioctl(fd_sec,SEC_SEND_SEQUENCE,&scmds) < 0) { perror("Error sending DisEqC"); return -1; } } #endif break; case FE_QAM: fprintf(stderr,"tuning DVB-C to %d, srate=%d\n",freq,srate); #ifdef NEWSTRUCT feparams.frequency=freq; feparams.inversion=INVERSION_OFF; feparams.u.qam.symbol_rate = srate; feparams.u.qam.fec_inner = FEC_AUTO; feparams.u.qam.modulation = modulation; #else feparams.Frequency=freq; feparams.Inversion=INVERSION_OFF; feparams.u.qam.SymbolRate = srate; feparams.u.qam.FEC_inner = FEC_AUTO; feparams.u.qam.QAM = modulation; #endif break; default: fprintf(stderr,"Unknown FE type. Aborting\n"); exit(-1); } usleep(100000); #ifndef NEWSTRUCT if (fd_sec) SecGetStatus(fd_sec, &sec_state); #endif return(check_status(fd_frontend,&feparams,tone)); } dvbtune-0.5/tune.h0000644000076400017500000000173707552337605014061 0ustar davedave00000000000000#ifndef _TUNE_H #define _TUNE_H #ifdef NEWSTRUCT #include #else // The following defines make the "OLDSTRUCT" driver more compatible with NEWSTRUCT. #include #define fe_status_t FrontendStatus #define fe_spectral_inversion_t SpectralInversion #define fe_modulation_t Modulation #define fe_code_rate_t CodeRate #define fe_transmit_mode_t TransmitMode #define fe_guard_interval_t GuardInterval #define fe_bandwidth_t BandWidth #define fe_sec_voltage_t SecVoltage #define dmx_pes_filter_params dmxPesFilterParams #define dmx_sct_filter_params dmxSctFilterParams #define dmx_pes_type_t dmxPesType_t #endif #include "dvb_defaults.h" int tune_it(int fd_frontend, int fd_sec, unsigned int freq, unsigned int srate, char pol, int tone, fe_spectral_inversion_t specInv, unsigned int diseqc,fe_modulation_t modulation,fe_code_rate_t HP_CodeRate,fe_transmit_mode_t TransmissionMode,fe_guard_interval_t guardInterval, fe_bandwidth_t bandwidth); #endif dvbtune-0.5/xml2vdr.c0000644000076400017500000002414207741322104014456 0ustar davedave00000000000000/* xml2vdr - a conversion utility to convert XML DVB-SI files into a channel list for VDR. It uses the SAX functions of libxml (version 2) - see www.xmlsoft.org (C) Dave Chapman, May 2001 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 #include #include #include #include /* This structure isn't used - it could be used to check the validity of the file. */ typedef enum { PARSER_START, PARSER_IN_SATELLITE, PARSER_IN_TRANSPONDER, PARSER_IN_SERVICE, PARSER_IN_STREAM, PARSER_END } ParserState; char service_name[256]; char provider_name[256]; int freq; char pol; char diseqc[]="S28.2E"; int srate; int vpid; int apid[256]; char ca_systems[256][256]; int n_ca; int is_ac3[256]; int n_apids=0; char lang[256][4]; char tmp[32]; int tpid; int ca; int pnr; int type; int ignore_service=0; int canal_radio_id; int in_audio_stream=0; int fta=0; /* A hack to clean text strings - it breaks on non-UK character sets */ void my_strcpy(unsigned char* dest, unsigned char* source) { int i=0; int j=0; while (source[j]!=0) { if (source[j]==':') { dest[i++]='|'; } else if ((source[j]>31) && (source[j]<128)) { dest[i++]=source[j]; } j++; } dest[i]=0; } static xmlEntityPtr xmlsat_GetEntity(void *user_data, const char *name) { return xmlGetPredefinedEntity(name); } typedef struct _xmlsatParseState { ParserState state; } xmlsatParseState; static void xmlsat_StartDocument(xmlsatParseState *state) { state->state = PARSER_START; } static void xmlsat_EndDocument(xmlsatParseState *state) { state->state = PARSER_END; } static void xmlsat_StartElement(xmlsatParseState *state, const char *name, const char **attrs) { int i; static int streamtype; static int pid; if (strcmp(name,"satellite")==0) { state->state=PARSER_IN_SATELLITE; } else if (strcmp(name,"transponder")==0) { state->state=PARSER_IN_TRANSPONDER; freq=0; pol='V'; srate=27500; if (attrs!=NULL) { for (i=0;attrs[i]!=NULL;i+=2) { if (strcmp(attrs[i],"freq")==0) { freq=atoi(attrs[i+1])/1000; } else if (strcmp(attrs[i],"srate")==0) { srate=atoi(attrs[i+1])/1000; } else if (strcmp(attrs[i],"polarity")==0) { pol=attrs[i+1][0]; } } } } else if (strcmp(name,"service")==0) { if (attrs!=NULL) { pnr=0; ca=0; for (i=0;attrs[i]!=NULL;i+=2) { if (strcmp(attrs[i],"id")==0) { pnr=atoi(attrs[i+1]); } } } } else if (strcmp(name,"stream")==0) { if (attrs!=NULL) { streamtype=0; pid=0; for (i=0;attrs[i]!=NULL;i+=2) { if (strcmp(attrs[i],"type")==0) { streamtype=atoi(attrs[i+1]); } else if (strcmp(attrs[i],"pid")==0) { pid=atoi(attrs[i+1]); } } if ((streamtype==1) || (streamtype==2)) { vpid=pid; } else if ((streamtype==3) || (streamtype==4)) { in_audio_stream=1; apid[n_apids]=pid; is_ac3[n_apids]=0; lang[n_apids][0]=0; n_apids++; } else if (streamtype==6) { // tpid=pid; } } } else if (strcmp(name,"ac3_descriptor")==0) { if (streamtype==6) { is_ac3[n_apids]=1; apid[n_apids]=pid; lang[n_apids][0]=0; n_apids++; in_audio_stream=1; } } else if (strcmp(name,"ca_system_descriptor")==0) { ca=1; for (i=0;attrs[i]!=NULL;i+=2) { if (strcmp(attrs[i],"system_id")==0) { if (strlen(attrs[i+1])>0) { strcpy(ca_systems[n_ca++],attrs[i+1]); } } } } else if (strcmp(name,"iso_639")==0) { if (in_audio_stream) { if (attrs!=NULL) { canal_radio_id=0; for (i=0;attrs[i]!=NULL;i+=2) { if (strcmp(attrs[i],"language")==0) { if (strlen(attrs[i+1])>0) { strcpy(lang[n_apids-1],attrs[i+1]); } } } } } } else if (strcmp(name,"canal_radio")==0) { ignore_service=1; if (attrs!=NULL) { canal_radio_id=0; for (i=0;attrs[i]!=NULL;i+=2) { if (strcmp(attrs[i],"id")==0) { canal_radio_id=atoi(attrs[i+1]); } else if (strcmp(attrs[i],"name")==0) { my_strcpy((unsigned char*)service_name,(unsigned char*)attrs[i+1]); } } } } else if (strcmp(name,"description")==0) { if (attrs!=NULL) { type=0; service_name[0]=0; provider_name[0]=0; for (i=0;attrs[i]!=NULL;i+=2) { if (strcmp(attrs[i],"service_name")==0) { my_strcpy((unsigned char*)service_name,(unsigned char*)attrs[i+1]); } else if (strcmp(attrs[i],"provider_name")==0) { my_strcpy((unsigned char*)provider_name,(unsigned char*)attrs[i+1]); } else if (strcmp(attrs[i],"type")==0) { type=atoi(attrs[i+1]); } } } } } static void xmlsat_EndElement(xmlsatParseState *state, const char *name) { int i,x; if (strcmp(name,"stream")==0) { in_audio_stream=0; } else if (strcmp(name,"canal_radio")==0) { // if (ca==0) printf("%s:RADIO:%s:%d:%c:%d:%d:%d:%d:%d:%d:%d\n",provider_name,service_name,freq,pol,diseqc,srate,vpid,apid[0],tpid,ca,pnr); if ((ca==0) || (fta==0)) printf("%s (RADIO):%d:%c:%s:%d:%d:%d:%d:%d:%d\n",service_name,freq,pol,diseqc,srate,vpid,apid[0],tpid,ca,pnr); n_apids=0; n_ca=0; } else if (strcmp(name,"service")==0) { if (service_name[0]==0) strcpy(service_name,"no name"); if ((ignore_service==0) && ((type==1) || (type==2) || (type==155))) { // TV or Radio or DishNetwork TV /* Only print service if at least 1 PID is non-zero */ if (((ca==0) || (fta==0)) && (((vpid!=0) || (n_apids>0) || (tpid!=0)))) { // printf("%s:%s:%s:%d:%c:%s:%d:%d:",provider_name,((vpid==0) ? "RADIO" : "TV"),service_name,freq,pol,diseqc,srate,vpid); printf("%s (%s):%d:%c:%s:%d:%d:",service_name,((vpid==0) ? "RADIO" : "TV"),freq,pol,diseqc,srate,vpid); x=0; for (i=0;i0) printf(","); // printf("%s",ca_systems[i]); // } } printf(":%d\n",pnr); } } service_name[0]=0; n_apids=0; n_ca=0; vpid=0; tpid=0; pnr=0; ca=0; type=0; ignore_service=0; } else if (strcmp(name,"transponder")==0) { freq=0; pol=0; srate=0; } } static void xmlsat_Characters(xmlsatParseState *state, const char *chars,int len) { // This is copied from a libxml example - it's not used in this application. // xmlsat files don't have any text elements - all data is stored as // attributes. /* switch (state->state) { case PARSER_IN_NAME: for (i = 0; i < len; i++) g_string_append_c(state->nameData, chars[i]); break; case PARSER_IN_SUMMARY: for (i = 0; i < len; i++) g_string_append_c(state->summaryData, chars[i]); break; default: break; } */ } static xmlSAXHandler xmlsatSAXParser = { 0, /* internalSubset */ 0, /* isStandalone */ 0, /* hasInternalSubset */ 0, /* hasExternalSubset */ 0, /* resolveEntity */ (getEntitySAXFunc)xmlsat_GetEntity, /* getEntity */ 0, /* entityDecl */ 0, /* notationDecl */ 0, /* attributeDecl */ 0, /* elementDecl */ 0, /* unparsedEntityDecl */ 0, /* setDocumentLocator */ (startDocumentSAXFunc)xmlsat_StartDocument, /* startDocument */ (endDocumentSAXFunc)xmlsat_EndDocument, /* endDocument */ (startElementSAXFunc)xmlsat_StartElement, /* startElement */ (endElementSAXFunc)xmlsat_EndElement, /* endElement */ 0, /* reference */ (charactersSAXFunc)xmlsat_Characters, /* characters */ 0, /* ignorableWhitespace */ 0, /* processingInstruction */ 0, /* comment */ 0, /* warning */ 0, /* error */ 0 /* fatalError */ }; int main(int argc, char **argv) { xmlParserCtxtPtr ctxt; xmlsatParseState state; if (argc<2) { printf("Usage: %s [-fta] filename.xmlsat\n",argv[0]); } else { if (argc==2) { ctxt = (xmlParserCtxtPtr)xmlCreateFileParserCtxt(argv[1]); } else if (argc==3) { if (strcmp(argv[1],"-fta")==0) { fta=1; } ctxt = (xmlParserCtxtPtr)xmlCreateFileParserCtxt(argv[2]); } if (ctxt == NULL) { fprintf(stderr,"ERROR: can not open file\n"); } ctxt->sax = &xmlsatSAXParser; ctxt->userData = &state; xmlParseDocument(ctxt); ctxt->sax = NULL; xmlFreeParserCtxt(ctxt); } return 0; }