All,
        The attached patch attempts to do a full scan for channels, i.e no
entering of tuning parameters. I've got it working for the UK, on my box
using a Nova-T :). I've also tried to enter some information for Finland
and Sweden, but I'm looking for information/feedback for more countries.

If you feel like entering more/fixing scanning information the places
you need to look at are ScanCountry in scanwizard.h for country chooser
widget, and the the top of siscan.cpp for the frequency/parameter
tables. (I hope the comments next to the structure are enough for you)

You're allowed more than one frequency band in a country spec. And for
each band you may also specify up to two offsets from the main centre
frequency (used in the UK and maybe Aus'). 

so

FrequencyTable frequenciesUK[]=
{

{474000000,850000000,8000000,INVERSION_OFF,BANDWIDTH_8_MHZ,FEC_AUTO,FEC_AUTO,QAM_AUTO,TRANSMISSION_MODE_2K,GUARD_INTERVAL_1_32,HIERARCHY_NONE,166670,-166670},
//Temination   
{0,0,0,INVERSION_AUTO,BANDWIDTH_AUTO,FEC_AUTO,FEC_AUTO,QAM_AUTO,TRANSMISSION_MODE_AUTO,GUARD_INTERVAL_AUTO,HIERARCHY_AUTO,0,0},
};
 
specifies a band between 474000000Hz and 850000000Hx stepped in
8000000Hz steps with two offsets (166670,-166670) to each frequency.
(All the other params are for the tuning options)

Please try this out, give me your feedback and include details of your
hardware, drivers etc.

P.S the code isn't quite production level, and I may have broken the
ATSC scan :)

Thanks
-- 
John Pullan <[EMAIL PROTECTED]>
Index: dvbchannel.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dvbchannel.cpp,v
retrieving revision 1.33
diff -u -r1.33 dvbchannel.cpp
--- dvbchannel.cpp	23 Mar 2005 06:45:36 -0000	1.33
+++ dvbchannel.cpp	31 Mar 2005 20:33:51 -0000
@@ -255,7 +255,11 @@
 
     GENERAL(QString("Successfully tuned to channel %1.").arg(chan));
 
-    if (!chan_opts.pmt.OnAir())
+    if (!chan_opts.pmt.OnAir()
+#ifdef DVB_RADIO
+ && !chan_opts.pmt.RadioService()
+#endif
+    )
     {
         ERROR(QString("Channel #%1 is off air.").arg(chan));
         return false;
@@ -1216,6 +1220,21 @@
     }
 }
 
+bool DVBChannel::GetFrontendParams(struct dvb_frontend_parameters *params)
+{
+    if (fd_frontend < 0)
+    {
+        ERROR("Card not open!");
+        return false;
+    }
+    if (ioctl(fd_frontend, FE_GET_FRONTEND, params) < 0)
+    {
+        ERRNO("Getting Frontend failed.");
+        return false;
+    }
+    return true;
+}
+
 bool DVBChannel::TuneQPSK(dvb_tuning_t& tuning, bool reset, bool& havetuned)
 {
     int frequency = tuning.params.frequency;
Index: dvbchannel.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/dvbchannel.h,v
retrieving revision 1.19
diff -u -r1.19 dvbchannel.h
--- dvbchannel.h	23 Mar 2005 06:45:36 -0000	1.19
+++ dvbchannel.h	31 Mar 2005 20:33:51 -0000
@@ -38,6 +38,7 @@
     void CloseDVB();
 
     fe_type_t GetCardType() { return info.type; };
+    bool GetFrontendParams(struct dvb_frontend_parameters *params);
 
     bool SetTransportByInt(int mplexid);
     bool SetChannelByString(const QString &chan);
Index: scanwizard.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/scanwizard.cpp,v
retrieving revision 1.9
diff -u -r1.9 scanwizard.cpp
--- scanwizard.cpp	29 Mar 2005 11:50:41 -0000	1.9
+++ scanwizard.cpp	31 Mar 2005 20:33:52 -0000
@@ -549,44 +549,67 @@
     }
 };
 
+class BlankSetting: public TransLabelSetting
+{
+public:
+     BlankSetting() : TransLabelSetting()
+     {
+         setLabel("");
+     }
+};
+
+ScanOptionalConfig::ScanOptionalConfig()
+{
+    setUseLabel(false);
+
+    scanType = new ScanTypeSetting();
+    addChild(scanType);
+    setTrigger(scanType);
+    // only save settings for the selected grabber
+    setSaveAll(false);
+    country = new ScanCountry();
+    addTarget(QString::number(ScanTypeSetting::FullScan),country);
+    addTarget(QString::number(ScanTypeSetting::FullTunedScan), 
+              new BlankSetting());
+    addTarget(QString::number(ScanTypeSetting::FullTransportScan), 
+              new BlankSetting());
+    transport = new TransportSetting();
+    addTarget(QString::number(ScanTypeSetting::TransportScan),transport);
+}
+
+
 ScanWizardScanType::ScanWizardScanType(ScanWizard *_parent) : parent(_parent)
 {
     setLabel(tr("Scan Type"));
     setUseLabel(false);
+
     videoSource = new VideoSourceSetting();
-    scanType = new ScanTypeSetting();
-    transport = new TransportSetting();
     capturecard = new CaptureCardSetting();
 
     addChild(videoSource);
     addChild(capturecard);
-    addChild(scanType);
-    addChild(transport);
+    scanConfig = new ScanOptionalConfig();
+    addChild(scanConfig);
 
     connect(videoSource, SIGNAL(valueChanged(const QString&)),
-        transport, SLOT(sourceID(const QString&)));
+        scanConfig->transport, SLOT(sourceID(const QString&)));
     connect(videoSource, SIGNAL(valueChanged(const QString&)),
         capturecard, SLOT(sourceID(const QString&)));
 
     connect(capturecard, SIGNAL(valueChanged(const QString&)),
         parent, SLOT(captureCard(const QString&)));
 
-    connect(scanType, SIGNAL(valueChanged(const QString&)),
+    connect(scanConfig->scanType, SIGNAL(valueChanged(const QString&)),
         this, SLOT(scanTypeChanged(const QString&)));
-    scanTypeChanged(scanType->getValue());
+    scanTypeChanged(scanConfig->scanType->getValue());
 }
 
 void ScanWizardScanType::scanTypeChanged(const QString& str)
 {
     unsigned nType = str.toInt();
     bool fEnable = false;
-    if ((nType == ScanTypeSetting::FullScan) ||
-        (nType == ScanTypeSetting::FullTransportScan))
-       transport->setEnabled(false);
-    if (nType == ScanTypeSetting::TransportScan)
-       transport->setEnabled(true);
-    if (nType == ScanTypeSetting::FullScan)
-        fEnable = true;
+    if (nType == ScanTypeSetting::FullTunedScan)
+       fEnable = true;
 
     parent->paneOFDM->enable(fEnable);
     parent->paneQPSK->enable(fEnable);
@@ -594,7 +617,6 @@
     parent->paneQAM->enable(fEnable);
 }
 
-
 ScanWizardTuningPage::ScanWizardTuningPage(ScanWizard *parent)
 {
     setLabel(tr("Tuning"));
@@ -718,7 +740,7 @@
                 connect(dvbchannel->siparser, SIGNAL(TableLoaded()),
                            this,SLOT(TableLoaded()));
                 popupProgress->progress((TUNED_PCT*PROGRESS_MAX)/100);
-                if (parent->scanType()==ScanTypeSetting::FullScan)
+                if (parent->scanType()==ScanTypeSetting::FullTunedScan)
                 {
                      if (parent->nCardType == CardUtil::ATSC)
                         scanner->ATSCScanTransport(parent->videoSource(),
@@ -726,6 +748,15 @@
                      else
                         scanner->ScanTransports();
                 }
+                else if (parent->scanType()==ScanTypeSetting::FullScan)
+                {
+                    if (parent->nCardType == CardUtil::ATSC)
+                        scanner->ATSCScanTransport(parent->videoSource(),
+                          parent->paneATSC->atscTransport());
+                    else if (parent->nCardType == CardUtil::OFDM)
+                        scanner->DVBTScanTransport(parent->videoSource(),
+                            parent->country());
+                }
                 else if (parent->scanType()==ScanTypeSetting::FullTransportScan)
                     transportScanComplete();
                 else
@@ -777,7 +808,7 @@
             return NULL;
         }
     }
-    else if (parent->scanType() == ScanTypeSetting::FullScan)
+    else if (parent->scanType() == ScanTypeSetting::FullTunedScan)
     {
         if (!scanner->dvbchannel->TuneTransport(scanner->chan_opts,true))
         {
@@ -806,6 +837,8 @@
 
 void ScanWizardScanner::updateText(const QString& str)
 {
+    if (str.isEmpty())
+         return;
     ScannerEvent* e=new ScannerEvent(ScanWizardScanner::ScannerEvent::Update);
     e->strValue(str);
     QApplication::postEvent(this,e);
@@ -961,7 +994,7 @@
     popupProgress->exec(this);
 
     memset(&chan_opts.tuning,0,sizeof(chan_opts.tuning));
-    if (parent->scanType() == ScanTypeSetting::FullScan)
+    if (parent->scanType() == ScanTypeSetting::FullTunedScan)
     {
         bool fParseError = false;
         switch (parent->nCardType)
@@ -1057,13 +1090,20 @@
             return;
         }
     }
+    else if (parent->scanType() == ScanTypeSetting::FullScan)
+    {
+       ScannerEvent* e=new ScannerEvent(ScanWizardScanner::ScannerEvent::TuneComplete);
+       e->intValue(ScanWizardScanner::ScannerEvent::OK);
+       QApplication::postEvent(this,e);
+       return;
+    }
 
     tunerthread_running = true;
     pthread_create(&tuner_thread, NULL, SpawnTune, this);
 }
 
-ScanWizard::ScanWizard() : nVideoDev(-1), nCardType(CardUtil::ERROR_PROBE), 
-    nCaptureCard(-1)
+ScanWizard::ScanWizard() : nVideoDev(-1),
+          nCardType(CardUtil::ERROR_PROBE), nCaptureCard(-1)
 {
     paneQPSK =  new QPSKPane();
     paneQAM = new QAMPane();
Index: scanwizard.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/scanwizard.h,v
retrieving revision 1.5
diff -u -r1.5 scanwizard.h
--- scanwizard.h	26 Mar 2005 15:16:49 -0000	1.5
+++ scanwizard.h	31 Mar 2005 20:33:52 -0000
@@ -45,6 +45,8 @@
 class QAMPane;
 class SIScan;
 class DVBChannel;
+class ScanOptionalConfig;
+class ScanCountry;
 
 class VideoSourceSetting: public ComboBoxSetting
 {
@@ -86,20 +88,47 @@
     void sourceID(const QString& str);
 };
 
+class ScanCountry: public ComboBoxSetting,TransientStorage
+{
+public:
+    enum Lang{UK,FI,SE};
+
+    ScanCountry()
+    {
+        setLabel(tr("Country"));
+        addSelection(QObject::tr("United Kingdom"),QString::number(UK));
+//        addSelection(tr("Germany"),QString::number(DE));
+        addSelection(QObject::tr("Finland"),QString::number(FI));
+        addSelection(QObject::tr("Sweden"),QString::number(SE));
+//        addSelection(tr("Australia"),QString::number(AU));
+    }
+};
+
 class ScanTypeSetting : public ComboBoxSetting, public TransientStorage
 {
 public:
-    enum Type {FullScan,FullTransportScan,TransportScan} ;
+    enum Type {FullScan,FullTunedScan,FullTransportScan,TransportScan} ;
 
     ScanTypeSetting()
     {
         setLabel(QObject::tr("Scan Type"));
         addSelection(tr("Full Scan"),QString::number(FullScan),true);
+        addSelection(tr("Full Scan (Tuned)"),QString::number(FullTunedScan));
         addSelection(tr("Full Scan of Existing Transports"),QString::number(FullTransportScan));
         addSelection(tr("Existing Transport Scan"),QString::number(TransportScan));
     }
 };
 
+class ScanOptionalConfig: public VerticalConfigurationGroup,
+                   public TriggeredConfigurationGroup {
+public:
+    ScanOptionalConfig();
+
+    ScanTypeSetting *scanType;
+    TransportSetting *transport;
+    ScanCountry *country;
+};
+
 class ScanWizardTuningPage;
 class ScanWizardScanner;
 
@@ -116,10 +145,9 @@
 protected:
     ScanWizard *parent;
 
-    TransportSetting *transport;
+    ScanOptionalConfig *scanConfig;
     CaptureCardSetting *capturecard;
     VideoSourceSetting *videoSource;
-    ScanTypeSetting *scanType;
 };
 
 class ScanWizard: public ConfigurationWizard 
@@ -155,9 +183,10 @@
 
     ScanWizardScanType *page1;
     int videoSource() {return page1->videoSource->getValue().toInt();}
-    int transport() {return page1->transport->getValue().toInt();}
+    int transport() {return page1->scanConfig->transport->getValue().toInt();}
+    int country() {return page1->scanConfig->country->getValue().toInt();}
     int captureCard() {return page1->capturecard->getValue().toInt();}
-    int scanType() {return page1->scanType->getValue().toInt();}
+    int scanType() {return page1->scanConfig->scanType->getValue().toInt();}
 };
 
 class ScanSignalMeter: public ProgressSetting, public TransientStorage {
Index: siscan.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/siscan.cpp,v
retrieving revision 1.12
diff -u -r1.12 siscan.cpp
--- siscan.cpp	27 Mar 2005 18:18:56 -0000	1.12
+++ siscan.cpp	31 Mar 2005 20:33:52 -0000
@@ -11,8 +11,205 @@
 
 
 #define CHECKNIT_TIMER 5000
+#define DVBTSCAN_TIMEOUT 40000
 //#define SISCAN_DEBUG
 
+struct FrequencyTable
+{
+    int frequencyStart;                 //The staring centre frequency
+    int frequencyEnd;                   //The ending centre frequency
+    int frequencyStep;                  //The step in frequency
+    fe_spectral_inversion_t inversion;
+    fe_bandwidth_t bandwidth;
+    fe_code_rate_t coderate_hp;
+    fe_code_rate_t coderate_lp;
+    fe_modulation_t constellation;  
+    fe_transmit_mode_t trans_mode; 
+    fe_guard_interval_t guard_interval;
+    fe_hierarchy_t hierarchy;
+    int offset1;                       //The first offset from the centre f'
+    int offset2;                       //The second offset from the center f'
+};
+
+FrequencyTable frequenciesUK[]=
+{
+   {474000000,850000000,8000000,INVERSION_OFF,BANDWIDTH_8_MHZ,FEC_AUTO,FEC_AUTO,QAM_AUTO,TRANSMISSION_MODE_2K,GUARD_INTERVAL_1_32,HIERARCHY_NONE,166670,-166670},
+   {0,0,0,INVERSION_AUTO,BANDWIDTH_AUTO,FEC_AUTO,FEC_AUTO,QAM_AUTO,TRANSMISSION_MODE_AUTO,GUARD_INTERVAL_AUTO,HIERARCHY_AUTO,0,0},
+};
+
+FrequencyTable frequenciesFI[]=
+{
+   {474000000,850000000,8000000,INVERSION_OFF,BANDWIDTH_8_MHZ,FEC_AUTO,FEC_AUTO,QAM_64,TRANSMISSION_MODE_AUTO,GUARD_INTERVAL_AUTO,HIERARCHY_NONE,0,0},
+   {0,0,0,INVERSION_AUTO,BANDWIDTH_AUTO,FEC_AUTO,FEC_AUTO,QAM_AUTO,TRANSMISSION_MODE_AUTO,GUARD_INTERVAL_AUTO,HIERARCHY_AUTO,0,0},
+};
+
+FrequencyTable frequenciesSE[]=
+{
+   {474000000,850000000,8000000,INVERSION_OFF,BANDWIDTH_8_MHZ,FEC_AUTO,FEC_AUTO,QAM_64,TRANSMISSION_MODE_AUTO,GUARD_INTERVAL_AUTO,HIERARCHY_NONE,0,0},
+   {0,0,0,INVERSION_AUTO,BANDWIDTH_AUTO,FEC_AUTO,FEC_AUTO,QAM_AUTO,TRANSMISSION_MODE_AUTO,GUARD_INTERVAL_AUTO,HIERARCHY_AUTO,0,0},
+};
+
+
+FrequencyTable *frequencies[]=
+{
+   frequenciesUK,
+   frequenciesFI,
+   frequenciesSE,
+};
+
+//Helper functions, need classing up
+QString paramToDbInversion(fe_spectral_inversion_t inversion)
+{ 
+    switch(inversion)
+    {
+    case INVERSION_ON:
+        return "1";
+    case INVERSION_OFF:
+        return "0";
+    default:
+        return "a";
+    }
+}
+
+QString paramToDbBandwidth(fe_bandwidth_t bandwidth)
+{
+    switch (bandwidth)
+    {
+       case BANDWIDTH_8_MHZ:
+           return "8";
+       case BANDWIDTH_7_MHZ:
+           return "7";
+       case BANDWIDTH_6_MHZ:
+           return "6";
+       default:
+               return "auto";
+    }
+}
+
+QString paramToDbCodeRate(fe_code_rate_t coderate)
+{
+    switch (coderate) 
+    {
+    case FEC_NONE:
+         return "none";
+    case FEC_1_2:
+        return "1/2";
+    case FEC_2_3:
+        return "2/3";
+    case FEC_3_4:
+        return "3/4";
+    case FEC_4_5:
+        return "4/5";
+    case FEC_5_6:
+        return "5/6";
+    case FEC_6_7:
+        return "6/7";
+    case FEC_7_8:
+        return "7/8";
+    default:
+        return "auto";
+    }
+}
+
+QString paramToDbConstellation(fe_modulation_t constellation)
+{
+    switch (constellation)
+    {
+       case QPSK:
+               return "qpsk";
+       case QAM_16:
+               return "qam_16";
+       case QAM_32:
+               return "qam_32";
+       case QAM_64:
+               return "qam_64";
+       case QAM_128:
+               return "qam_128";
+       case QAM_256:
+               return "qam_256";
+       default:
+               return "auto";
+    }
+}
+
+QString paramToDbTransmissionMode(fe_transmit_mode_t transmission_mode)
+{
+    //TransmissionMode
+    switch (transmission_mode) 
+    {
+    case TRANSMISSION_MODE_2K:
+        return "2";
+    case TRANSMISSION_MODE_8K:
+        return "8";
+    default:
+        return "auto";
+    }    
+}
+
+QString paramToDbGuardInterval(fe_guard_interval_t guard_interval)
+{
+    //Guard Interval
+    switch (guard_interval) 
+    {
+    case GUARD_INTERVAL_1_32:
+        return "1/32";
+    case GUARD_INTERVAL_1_16:
+        return "1/16";
+    case GUARD_INTERVAL_1_8:
+        return "1/8";
+    case GUARD_INTERVAL_1_4:
+        return "1/4";
+    default:
+        return "auto";
+    } 
+}
+
+QString paramToDbHierarchy(fe_hierarchy_t hierarchy)
+{
+   // Hierarchy
+    switch (hierarchy) 
+    {
+       case HIERARCHY_NONE:
+               return "n";
+       case HIERARCHY_1:
+               return "1";
+       case HIERARCHY_2:
+               return "2";
+       case HIERARCHY_4:
+               return "4";
+       default:
+               return "a";
+    }
+}
+
+QString paramToDbModulation(fe_modulation_t modulation)
+{
+    switch(modulation)
+    {
+        case QPSK:
+            return "qpsk";
+        case QAM_16:
+            return "qam_16";
+        case QAM_32:  
+            return "qam_32";
+        case QAM_64:   
+            return "qam_64";
+        case QAM_128:
+            return "qam_128";
+        case QAM_256:
+            return "qam_256";
+#if (DVB_API_VERSION_MINOR == 1)
+        case VSB_8:
+            return "8vsb";
+        case VSB_16:
+            return "16vsb";
+#endif
+        case QAM_AUTO:
+        default:
+            return "auto";
+    }
+}
+
 SIScan::SIScan(DVBChannel* advbchannel, int _sourceID)
 {
     /* setup links to parents and db connections */
@@ -29,6 +226,7 @@
     ScanTimeout = 0; 		/* Set scan timeout off by default */
 
     FTAOnly = false;
+    RadioServices = false;
     forceUpdate = false;
 
     pthread_mutex_init(&events_lock, NULL);
@@ -61,7 +259,6 @@
 
 bool SIScan::ScanServicesSourceID(int SourceID)
 {
-
     if (scanMode == TRANSPORT_LIST)
         return false;
 
@@ -110,6 +307,59 @@
     return chan->siparser->FindServices();
 }
 
+int SIScan::CreateTransport(const fe_type_t cardType,
+                            const TransportScanList& a, 
+                            const dvb_frontend_parameters& fe)
+{
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare("INSERT into dtv_multiplex (frequency, "
+                   "sistandard, sourceid,inversion,bandwidth,hp_code_rate,lp_code_rate,constellation,transmission_mode,guard_interval,hierarchy,modulation) "
+                   "VALUES (:FREQUENCY,:STANDARD,:SOURCEID,:INVERSION,:BANDWIDTH,:CODERATE_HP,:CODERATE_LP,:CONSTELLATION,:TRANS_MODE,:GUARD_INTERVAL,:HIERARCHY,:MODULATION);");
+    query.bindValue(":STANDARD",a.standard);
+    query.bindValue(":FREQUENCY",fe.frequency);
+    query.bindValue(":SOURCEID",a.SourceID);
+
+    switch (cardType)
+    {
+    case FE_QAM: //TODO
+    case FE_QPSK:
+         break;
+    case FE_OFDM:
+        query.bindValue(":INVERSION",paramToDbInversion(fe.inversion));
+        query.bindValue(":BANDWIDTH",paramToDbBandwidth(fe.u.ofdm.bandwidth));
+        query.bindValue(":CODERATE_HP",paramToDbCodeRate(fe.u.ofdm.code_rate_HP));
+        query.bindValue(":CODERATE_LP",paramToDbCodeRate(fe.u.ofdm.code_rate_LP));
+        query.bindValue(":CONSTELLATION",paramToDbConstellation(fe.u.ofdm.constellation));
+        query.bindValue(":TRANS_MODE",paramToDbTransmissionMode(fe.u.ofdm.transmission_mode));
+        query.bindValue(":GUARD_INTERVAL",paramToDbGuardInterval(fe.u.ofdm.guard_interval));
+        query.bindValue(":HIERARCHY",paramToDbHierarchy(fe.u.ofdm.hierarchy_information));
+        break; 
+#if (DVB_API_VERSION_MINOR == 1)
+         case FE_ATSC:
+             query.bindValue(":MODULATION",paramToDbModulation(fe.u.vsb.modulation));
+         break; 
+#endif
+    }
+
+    if(!query.exec())
+        MythContext::DBError("Inserting new transport", query);
+    if (!query.isActive())
+         MythContext::DBError("Adding transport to Database.", query);
+    query.prepare("select max(mplexid) from dtv_multiplex;");
+    if(!query.exec())
+        MythContext::DBError("Getting ID of new Transport", query);
+    if (!query.isActive())
+        MythContext::DBError("Getting ID of new Transport.", query);
+
+    int transport = -1;
+    if (query.size() > 0)
+    {
+        query.next();
+        transport = query.value(0).toInt();
+    }
+    return transport;
+}
+ 
 void SIScan::StartScanner()
 {
     SIPARSER("Starting SIScanner");
@@ -145,14 +395,6 @@
             {
 
                 /* We could just look at the transportsCount here but it's not really thread safe */
-/*                QValueList<TransportScanList>::Iterator i;
-                bool fAll = true;
-                for (i = scanTransports.begin() ; i != scanTransports.end() && fAll ; ++i)
-                    if (!(*i).complete)
-                        fAll = false;
-                if (fAll)
-                    emit ServiceScanComplete();
-*/
                 emit PctServiceScanComplete(((transportsToScan-transportsCount)*100)/transportsToScan);
                 sourceIDTransportTuned = false;
             }
@@ -197,17 +439,36 @@
                             scanMode = IDLE; 
          
                         bool result = false;                
+                        dvb_channel_t t;
                         if ((*i).mplexid == -1)
                         {
                             /* For ATSC / Cable try for 2 seconds to tune otherwise give up */
-                            dvb_channel_t t;
-                            t.tuning = (*i).tuning;
-                            t.sistandard = "atsc";
-                            result = chan->TuneTransport(t,true,2000);
+                            t.sistandard =  (*i).standard;
+                            result=0;
+
+                            if ((*i).offset1)
+                            {
+                                t.tuning = (*i).tuning;
+                                t.tuning.params.frequency+=(*i).offset1;
+                                result = chan->TuneTransport(t,true,(*i).timeoutTune);
+                            }
+                            
+                            if (!result && (*i).offset2)
+                            {
+                                t.tuning = (*i).tuning;
+                                t.tuning.params.frequency+=(*i).offset2;
+                                result = chan->TuneTransport(t,true,(*i).timeoutTune);
+                            }
+
+                            if (!result)
+                            {
+                                t.tuning = (*i).tuning;
+                                result = chan->TuneTransport(t,true,(*i).timeoutTune);
+                            }
                         }
                         else 
                             result = chan->SetTransportByInt((*i).mplexid);
-
+        
                         if (!result)
                         {
                             int pct = ((transportsToScan-transportsCount)*100)/transportsToScan;
@@ -220,31 +481,18 @@
                         {
                             if ((*i).mplexid == -1)
                             {
-                                MSqlQuery query(MSqlQuery::InitCon());
-                                query.prepare("INSERT into dtv_multiplex (frequency, "
-                                               "modulation, sistandard, sourceid) "
-                                               "VALUES (:FREQUENCY,:MODULATION,\"atsc\",:SOURCEID);");
-                                query.bindValue(":FREQUENCY",(*i).Frequency);
-                                query.bindValue(":MODULATION",(*i).Modulation);
-                                query.bindValue(":SOURCEID",(*i).SourceID);
-                                if(!query.exec())
-                                    MythContext::DBError("Inserting new transport", query);
-                                if (!query.isActive())
-                                     MythContext::DBError("Adding transport to Database.", query);
-
-                                query.prepare("select max(mplexid) from dtv_multiplex;");
-                                if(!query.exec())
-                                    MythContext::DBError("Getting ID of new Transport", query);
-                                if (!query.isActive())
-                                    MythContext::DBError("Getting ID of new Transport.", query);
-
-                                if (query.size() > 0)
-                                {
-                                    query.next();
-                                    chan->SetCurrentTransportDBID(query.value(0).toInt());
-                                }
-
+                                int transport;
+                                struct dvb_frontend_parameters fe;
+                                //read the actual values back from the card
+                                if (chan->GetFrontendParams(&fe))
+                                    transport = CreateTransport(chan->GetCardType(),(*i),fe);
+                                else
+                                    transport = CreateTransport(chan->GetCardType(),(*i),(*i).tuning.params);
+                                if (transport >=0) 
+                                    chan->SetCurrentTransportDBID(transport);
                             }
+                            else
+                                chan->SetCurrentTransportDBID((*i).mplexid);
                             timer.start();
                             chan->siparser->FindServices();
                             sourceIDTransportTuned = true;
@@ -271,13 +519,13 @@
 
 bool SIScan::ATSCScanTransport(int SourceID, int FrequencyBand)
 {
-
+#if (DVB_API_VERSION_MINOR == 1)
     if (scanMode == TRANSPORT_LIST)
         return false;
 
     struct CHANLIST* curList;
-    QString Modulation;
     QString NamePrefix;
+    fe_modulation_t modulation;
 
     switch (FrequencyBand)
     {
@@ -285,13 +533,13 @@
                    curList = chanlists[0].list;
                    /* Ensure scan only does 2-69 */
                    transportsCount = transportsToScan = 68;
-                   Modulation = "8vsb";
+                   modulation = VSB_8;
                    NamePrefix = "ATSC Channel";
                    break;
         case 1:
                    curList = chanlists[1].list;
                    transportsCount = transportsToScan = chanlists[1].count; 
-                   Modulation = "qam_256";
+                   modulation = QAM_256;
                    NamePrefix = "QAM Channel";
                    break;
         default:
@@ -307,38 +555,138 @@
     for (int x = 0 ; x < transportsToScan ; x++)
     {
         TransportScanList a;
+        a.standard="atsc";
+        a.timeoutTune = TransportScanList::ATSC_TUNINGTIMEOUT;
         uint32_t freq = (curList[x].freq + 1750) * 1000;
         a.FriendlyName = QString("%1 %2").arg(NamePrefix).arg(curList[x].name);
-        QString Frequency = QString("%1").arg(freq);
-        a.Frequency = Frequency;
-        a.Modulation = Modulation;
+        a.tuning.params.frequency = freq;
+        a.tuning.params.u.vsb.modulation = modulation;
         a.SourceID = SourceID;
-        chan->ParseATSC(Frequency,Modulation,a.tuning);
 
         /* See if mplexid is already in the database */
-        QString theQuery = QString("select mplexid from dtv_multiplex where "
-                           "sourceid = %1 and frequency = %2")
-                           .arg(SourceID)
-                           .arg(Frequency);
+        verifyTransport(a);
+    }    
+
+    timer.start();
+    ScanTimeout = CHECKNIT_TIMER;
+    sourceIDTransportTuned = false;
+    scanMode = TRANSPORT_LIST;    
+    return true;
+#else
+    (void)SourceID;
+    (void)FrequencyBand;
+    return false;
+#endif
+}
+
+void SIScan::verifyTransport(TransportScanList& t)
+{
+    MSqlQuery query(MSqlQuery::InitCon());
+    /* See if mplexid is already in the database */
+    QString theQuery = QString("select mplexid from dtv_multiplex where "
+                       "sourceid = %1 and frequency = %2")
+                       .arg(t.SourceID)
+                       .arg(t.tuning.params.frequency);
+    query.prepare(theQuery);
+
+    if (!query.exec() || !query.isActive())
+        MythContext::DBError("Check for existing transport", query);
+
+    if (query.size() > 0)
+    {
+        query.next();
+        t.mplexid = query.value(0).toInt();            
+        return;
+    }
 
+    if (t.offset1)
+    {
+        theQuery = QString("select mplexid from dtv_multiplex where "
+                       "sourceid = %1 and frequency = %2")
+                       .arg(t.SourceID)
+                       .arg(t.tuning.params.frequency+t.offset1);
         query.prepare(theQuery);
-    
+
         if (!query.exec() || !query.isActive())
             MythContext::DBError("Check for existing transport", query);
-    
-        if (query.size() <= 0)
-            a.mplexid = -1;
-        else
+
+        if (query.size() > 0)
         {
             query.next();
-            a.mplexid = query.value(0).toInt();            
+            t.mplexid = query.value(0).toInt();            
+            return;
         }
-        scanTransports += a;
+    }
 
-    }    
+    if (t.offset2)
+    {
+        theQuery = QString("select mplexid from dtv_multiplex where "
+                       "sourceid = %1 and frequency = %2")
+                       .arg(t.SourceID)
+                       .arg(t.tuning.params.frequency+t.offset2);
+        query.prepare(theQuery);
+
+        if (!query.exec() || !query.isActive())
+            MythContext::DBError("Check for existing transport", query);
+
+        if (query.size() > 0)
+        {
+            query.next();
+            t.mplexid = query.value(0).toInt();            
+            return;
+        }
+    }
+
+    t.mplexid = -1;
+}
+
+bool SIScan::DVBTScanTransport(int SourceID,unsigned country)
+{
+    if (scanMode == TRANSPORT_LIST)
+        return false;
+
+    scanTransports.clear();
+	
+    /* Now generate a list of frequencies to scan and add it to the atscScanTransportList */
+
+    MSqlQuery query(MSqlQuery::InitCon());
+
+    transportsCount=0;
+    FrequencyTable *t = frequencies[country];
+    while (t && t->frequencyStart)
+    {
+        FrequencyTable *f = t;
+        for (int x = f->frequencyStart ;x<=f->frequencyEnd; x+=f->frequencyStep)
+        {
+            TransportScanList a;
+            a.SourceID = SourceID;
+            a.standard="dvb";
+            a.timeoutTune = TransportScanList::DVBT_TUNINGTIMEOUT;
+            
+            a.tuning.params.frequency = x;
+            a.tuning.params.inversion = f->inversion;
+            a.tuning.params.u.ofdm.bandwidth = f->bandwidth;
+            a.tuning.params.u.ofdm.code_rate_HP = f->coderate_hp;
+            a.tuning.params.u.ofdm.code_rate_LP = f->coderate_lp;
+            a.tuning.params.u.ofdm.constellation = f->constellation;
+            a.tuning.params.u.ofdm.transmission_mode = f->trans_mode;
+            a.tuning.params.u.ofdm.guard_interval = f->guard_interval;
+            a.tuning.params.u.ofdm.hierarchy_information = f->hierarchy;
+            
+            a.offset1 = f->offset1;
+            a.offset2 = f->offset2;
 
+            verifyTransport(a); 
+            
+            scanTransports += a;
+            transportsCount++;
+        }    
+        t++;
+    }
+    
+    transportsToScan=transportsCount;
     timer.start();
-    ScanTimeout = CHECKNIT_TIMER;
+    ScanTimeout = DVBTSCAN_TIMEOUT;
     sourceIDTransportTuned = false;
     scanMode = TRANSPORT_LIST;    
     return true;
@@ -371,7 +719,6 @@
 
 void SIScan::UpdateServicesInDB(QMap_SDTObject SDT)
 {
-
     /* This will be fixed post .17 to be more elegant */
     int localSourceID = -1;
 
@@ -440,7 +787,6 @@
     if (!query.isActive())
          MythContext::DBError("Check Channel full in channel/dtv_multiplex.", query);
 
-
     if (query.size() > 0)
     {
         query.next();
@@ -470,8 +816,11 @@
     }
 
 // Get the freetoaironly field from cardinput 
-
-    QString FTAQuery = QString("SELECT freetoaironly from cardinput,dtv_multiplex, "
+    QString FTAQuery = QString("SELECT freetoaironly "
+#ifdef DVB_RADIO
+                               ",radioservices " 
+#endif
+                               "from cardinput,dtv_multiplex, "
                                "capturecard WHERE "
                                "cardinput.sourceid = dtv_multiplex.sourceid AND "
                                "cardinput.cardid = capturecard.cardid AND "
@@ -483,24 +832,22 @@
     if(!query.exec())      
         MythContext::DBError("Getting FreeToAir for cardinput", query);
             
-    if (!query.isActive())
-        MythContext::DBError("Getting FreeToAir for cardinput", query);
-
     if (query.size() > 0)
     {
         query.next();
-        FTAOnly = query.value(0).toInt();
+        FTAOnly = query.value(0).toBool();
+#ifdef DVB_RADIO
+        RadioServices = query.value(1).toBool();
+#endif
     }
     else
-    {
         return;    
-    }
 
 // TODO: Process Steps 3 and 4.. Only a partial 4 is being done now..
     for (s = SDT.begin() ; s != SDT.end() ; ++s )
     {
         // Its a TV Service so add it also only do FTA
-        if(((*s).ServiceType == 1) &&
+        if((((*s).ServiceType==1) || ((*s).ServiceType==2) && RadioServices) &&
            (!FTAOnly || (FTAOnly && ((*s).CAStatus == 0))))
         {
             // See if transport already in database based on serviceid,networkid  and transportid
@@ -521,7 +868,6 @@
             // If channel not present add it
             if (query.size() <= 0)
             {
-
                     if ((*s).ServiceName.stripWhiteSpace().isEmpty())
                     {
                         (*s).ServiceName = "Unnamed Channel";
@@ -596,7 +942,6 @@
                 emit ServiceScanUpdateText(status);
             }
     }
-
 }
 
 void SIScan::CheckNIT(NITObject& NIT)
Index: siscan.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/siscan.h,v
retrieving revision 1.3
diff -u -r1.3 siscan.h
--- siscan.h	23 Feb 2005 05:04:36 -0000	1.3
+++ siscan.h	31 Mar 2005 20:33:52 -0000
@@ -15,32 +15,43 @@
 class TransportScanList
 {
 public:
+    enum {DVBT_TUNINGTIMEOUT=1000, ATSC_TUNINGTIMEOUT=2000};
+
     TransportScanList()
     {
         mplexid = -1;
         complete = false;
         scanning = false;
-        Frequency = "";
-        Modulation = "";
         FriendlyName = "";
+        offset1 = 0;
+        offset2 = 0;
+        timeoutTune = ATSC_TUNINGTIMEOUT; 
     }
+
     TransportScanList(int _mplexid)
     {
         mplexid = _mplexid;
         complete = false;
         scanning = false;
+        FriendlyName = "";
+        offset1 = 0;
+        offset2 = 0;
+        timeoutTune = ATSC_TUNINGTIMEOUT; 
     }
+
     int mplexid;                /* DB Mplexid */
     bool complete;              /* scan status */
+    QString standard;           /* DVB/ATSC */
     dvb_tuning_t tuning;        /* DVB Tuning struct if mplexid == -1 */
+
     QString FriendlyName;       /* Name to display in scanner dialog */
-    QString Frequency;          /* Frequency as QString */
-    QString Modulation;         /* Modulation as QString */
     int SourceID;               /* Associated SourceID */
     bool UseTimer;              /* Set if timer is used after lock for getting PAT */
 
     bool scanning;              /* Probbably Unnecessary */
-
+    int offset1;                /* First frequency offset */
+    int offset2;                /* Second frequency offset */
+    unsigned timeoutTune;      /* Timeout to tune to a frequency*/
 };
 
 class SIScan : public QObject
@@ -56,12 +67,14 @@
     void StopScanner();
 
     bool ATSCScanTransport(int SourceID, int FrequencyBand);
+    bool DVBTScanTransport(int SourceID, unsigned country);
     bool ScanTransports();
     bool ScanServices(int TransportID = -1);
     bool ScanServicesSourceID(int SourceID);
     void SetSourceID(int _SourceID);
 
     void SetFTAOnly(bool _fFTAOnly) { FTAOnly = _fFTAOnly;}
+    void SetRadioServices(bool _fRadio) { RadioServices = _fRadio;}
     void SetForceUpdate(bool _force) { forceUpdate = _force;}
     void SetScanTimeout(int _timeout) { ScanTimeout = _timeout;}
 
@@ -86,6 +99,11 @@
     static void *ServiceScanThreadHelper(void*);
     static void *TransportScanThreadHelper(void*);
 
+    void verifyTransport(TransportScanList& t);
+
+    int CreateTransport(const fe_type_t cardType,const TransportScanList& a,
+                    const dvb_frontend_parameters& fe);
+
     void UpdateTransportsInDB(NITObject NIT);
     void CheckNIT(NITObject& NIT);
 
@@ -114,6 +132,7 @@
 
     bool threadExit;
     bool FTAOnly;
+    bool RadioServices;
     bool forceUpdate;
     int ScanTimeout;
     SCANMODE scanMode;
_______________________________________________
mythtv-dev mailing list
[email protected]
http://mythtv.org/cgi-bin/mailman/listinfo/mythtv-dev

Reply via email to