#include <lib/dvb/scan.h>
#include <lib/dvb/frontend.h>
#include <lib/base/eerror.h>
+#include <lib/base/estring.h>
#include <errno.h>
#define SCAN_eDebug(x...) eDebug(x)
{
}
-int eDVBScan::isValidONIDTSID(eOriginalNetworkID onid, eTransportStreamID tsid)
+int eDVBScan::isValidONIDTSID(int orbital_position, eOriginalNetworkID onid, eTransportStreamID tsid)
{
switch (onid.get())
{
case 0:
- case 0xFFFF:
case 0x1111:
return 0;
case 1:
- return tsid>1;
+ return orbital_position == 192;
case 0x00B1:
return tsid != 0x00B0;
case 0x0002:
- return tsid != 0x07E8;
+ return abs(orbital_position-282) < 6;
default:
- return 1;
+ return onid.get() < 0xFF00;
}
}
eDVBNamespace eDVBScan::buildNamespace(eOriginalNetworkID onid, eTransportStreamID tsid, unsigned long hash)
{
// on valid ONIDs, ignore frequency ("sub network") part
- if (isValidONIDTSID(onid, tsid))
+ if (isValidONIDTSID((hash >> 16) & 0xFFFF, onid, tsid))
hash &= ~0xFFFF;
return eDVBNamespace(hash);
}
{
startFilter();
m_channel_state = state;
- } else if (state == iDVBChannel::state_unavailable)
+ } else if (state == iDVBChannel::state_failed)
{
m_ch_unavailable.push_back(m_ch_current);
nextChannel();
}
+ /* unavailable will timeout, anyway. */
}
RESULT eDVBScan::nextChannel()
m_SDT = 0; m_BAT = 0; m_NIT = 0;
- m_ready = readyBAT;
+ m_ready = 0;
+
+ /* check what we need */
+ m_ready_all = readySDT;
+
+ if (m_flags & scanNetworkSearch)
+ m_ready_all |= readyNIT;
+
+ if (m_flags & scanSearchBAT)
+ m_ready_all |= readyBAT;
+
if (m_ch_toScan.empty())
{
eDebug("no channels left to scan.");
}
m_ch_current = m_ch_toScan.front();
- m_chid_current = eDVBChannelID();
m_ch_toScan.pop_front();
m_event(evtFail);
return -ENOTSUP;
}
-
+
+ int fetype;
+ fe->getFrontendType(fetype);
+ if ( fetype == iDVBFrontend::feSatellite)
+ {
+ eDVBFrontendParametersSatellite p;
+ m_ch_current->getDVBS(p);
+ m_chid_current = eDVBChannelID(p.orbital_position << 16, -1, -1);
+ }
+ else
+ m_chid_current = eDVBChannelID();
+
m_channel_state = iDVBChannel::state_idle;
if (fe->tune(*m_ch_current))
{
{
assert(m_demux);
- m_SDT = new eTable<ServiceDescriptionSection>();
- if (m_SDT->start(m_demux, eDVBSDTSpec()))
- return -1;
- CONNECT(m_SDT->tableReady, eDVBScan::SDTready);
+ /* only start required filters filter */
+
+ m_SDT = 0;
+
+ if (m_ready_all & readySDT)
+ {
+ m_SDT = new eTable<ServiceDescriptionSection>();
+ if (m_SDT->start(m_demux, eDVBSDTSpec()))
+ return -1;
+ CONNECT(m_SDT->tableReady, eDVBScan::SDTready);
+ }
m_NIT = 0;
- m_NIT = new eTable<NetworkInformationSection>();
- if (m_NIT->start(m_demux, eDVBNITSpec()))
- return -1;
- CONNECT(m_NIT->tableReady, eDVBScan::NITready);
-
- m_BAT = new eTable<BouquetAssociationSection>();
- if (m_BAT->start(m_demux, eDVBBATSpec()))
- return -1;
- CONNECT(m_BAT->tableReady, eDVBScan::BATready);
+ if (m_ready_all & readyNIT)
+ {
+ m_NIT = new eTable<NetworkInformationSection>();
+ if (m_NIT->start(m_demux, eDVBNITSpec()))
+ return -1;
+ CONNECT(m_NIT->tableReady, eDVBScan::NITready);
+ }
+
+ m_BAT = 0;
+ if (m_ready_all & readyBAT)
+ {
+ m_BAT = new eTable<BouquetAssociationSection>();
+ if (m_BAT->start(m_demux, eDVBBATSpec()))
+ return -1;
+ CONNECT(m_BAT->tableReady, eDVBScan::BATready);
+ }
return 0;
}
return;
/* otherwise, add it to the todo list. */
- m_ch_toScan.push_back(feparm);
+ m_ch_toScan.push_front(feparm); // better.. then the rotor not turning wild from east to west :)
}
int eDVBScan::sameChannel(iDVBFrontendParameters *ch1, iDVBFrontendParameters *ch2) const
feparm->getHash(hash);
eDVBNamespace ns = buildNamespace(onid, tsid, hash);
-
- addChannelToScan(
- eDVBChannelID(ns, tsid, onid),
- feparm);
+
+ if ( m_chid_current.dvbnamespace.get() != -1 &&
+ ((ns.get() ^ m_chid_current.dvbnamespace.get()) & 0xFFFF0000))
+ eDebug("dropping this transponder, it's on another satellite.");
+ else
+ {
+ addChannelToScan(
+ eDVBChannelID(ns, tsid, onid),
+ feparm);
+ }
break;
}
default:
m_ready &= ~validNIT;
}
- if ((m_ready & readyAll) != readyAll)
+ if ((m_ready & m_ready_all) != m_ready_all)
return;
SCAN_eDebug("channel done!");
nextChannel();
}
-void eDVBScan::start(const std::list<ePtr<iDVBFrontendParameters> > &known_transponders)
+void eDVBScan::start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags)
{
+ m_flags = flags;
m_ch_toScan.clear();
m_ch_scanned.clear();
m_ch_unavailable.clear();
m_new_channels.clear();
m_new_services.clear();
- m_ch_toScan.insert(m_ch_toScan.end(), known_transponders.begin(), known_transponders.end());
+
+ for (eSmartPtrList<iDVBFrontendParameters>::const_iterator i(known_transponders.begin()); i != known_transponders.end(); ++i)
+ {
+ bool exist=false;
+ for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator ii(m_ch_toScan.begin()); ii != m_ch_toScan.end(); ++ii)
+ {
+ if (sameChannel(*i, *ii))
+ {
+ exist=true;
+ break;
+ }
+ }
+ if (!exist)
+ m_ch_toScan.push_back(*i);
+ }
+
nextChannel();
}
case SERVICE_DESCRIPTOR:
{
ServiceDescriptor &d = (ServiceDescriptor&)**desc;
- SCAN_eDebug("name '%s', provider_name '%s'", d.getServiceName().c_str(), d.getServiceProviderName().c_str());
- service->m_service_name = d.getServiceName();
- service->m_provider_name = d.getServiceProviderName();
+ service->m_service_name = convertDVBUTF8(d.getServiceName());
+ service->genSortName();
+
+ service->m_provider_name = convertDVBUTF8(d.getServiceProviderName());
+ SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str());
break;
}
case CA_IDENTIFIER_DESCRIPTOR: