#include <dvbsi++/descriptor_tag.h>
#include <dvbsi++/service_descriptor.h>
#include <dvbsi++/satellite_delivery_system_descriptor.h>
+#include <dvbsi++/terrestrial_delivery_system_descriptor.h>
+#include <dvbsi++/cable_delivery_system_descriptor.h>
#include <dvbsi++/ca_identifier_descriptor.h>
#include <lib/dvb/specs.h>
#include <lib/dvb/esection.h>
#include <lib/base/eerror.h>
#include <lib/base/estring.h>
#include <errno.h>
+#include <set>
#define SCAN_eDebug(x...) eDebug(x)
#define SCAN_eDebugNoNewLine(x...) eDebugNoNewLine(x)
DEFINE_REF(eDVBScan);
-eDVBScan::eDVBScan(iDVBChannel *channel): m_channel(channel)
+eDVBScan::eDVBScan(iDVBChannel *channel)
+ :m_channel(channel), m_ready(0), m_flags(0), m_ready_all(readySDT)
+ ,m_channel_state(iDVBChannel::state_idle)
{
if (m_channel->getDemux(m_demux))
SCAN_eDebug("scan: failed to allocate demux!");
if (m_ch_toScan.empty())
{
- eDebug("no channels left to scan.");
- eDebug("%d channels scanned, %d were unavailable.",
- m_ch_scanned.size(), m_ch_unavailable.size());
- eDebug("%d channels in database.", m_new_channels.size());
+// SCAN_eDebug("no channels left to scan.");
+// SCAN_eDebug("%d channels scanned, %d were unavailable.",
+// m_ch_scanned.size(), m_ch_unavailable.size());
+// SCAN_eDebug("%d channels in database.", m_new_channels.size());
m_event(evtFinish);
return -ENOENT;
}
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
if (m_ready & validSDT)
{
unsigned long hash = 0;
+
+ // m_ch_current is not set, when eDVBScan is just used for a SDT update
+ if (!m_ch_current)
+ m_channel->getCurrentFrontendParameters(m_ch_current);
+
m_ch_current->getHash(hash);
eDVBNamespace dvbnamespace = buildNamespace(
{
switch ((*desc)->getTag())
{
-// case SERVICE_LIST_DESCRIPTOR:
+ case CABLE_DELIVERY_SYSTEM_DESCRIPTOR:
+ {
+ CableDeliverySystemDescriptor &d = (CableDeliverySystemDescriptor&)**desc;
+ ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
+ eDVBFrontendParametersCable cable;
+ cable.set(d);
+ feparm->setDVBC(cable);
+
+ unsigned long hash=0;
+ feparm->getHash(hash);
+ eDVBNamespace ns = buildNamespace(onid, tsid, hash);
+
+ addChannelToScan(
+ eDVBChannelID(ns, tsid, onid),
+ feparm);
+ break;
+ }
+ case TERRESTRIAL_DELIVERY_SYSTEM_DESCRIPTOR:
+ {
+ TerrestrialDeliverySystemDescriptor &d = (TerrestrialDeliverySystemDescriptor&)**desc;
+ ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
+ eDVBFrontendParametersTerrestrial terr;
+ terr.set(d);
+ feparm->setDVBT(terr);
+
+ unsigned long hash=0;
+ feparm->getHash(hash);
+ eDVBNamespace ns = buildNamespace(onid, tsid, hash);
+
+ addChannelToScan(
+ eDVBChannelID(ns, tsid, onid),
+ feparm);
+ break;
+ }
case SATELLITE_DELIVERY_SYSTEM_DESCRIPTOR:
{
SatelliteDeliverySystemDescriptor &d = (SatelliteDeliverySystemDescriptor&)**desc;
- SCAN_eDebug("%d kHz, %d%d%d.%d%c %s MOD:%d %d symb/s, fec %d",
- d.getFrequency(),
- (d.getOrbitalPosition()>>12)&0xF,
- (d.getOrbitalPosition()>>8)&0xF,
- (d.getOrbitalPosition()>>4)&0xF,
- d.getOrbitalPosition()&0xF, d.getWestEastFlag()?'E':'W',
- d.getPolarization() ? "hor" : "vert",
- d.getModulation(), d.getSymbolRate(), d.getFecInner());
-
- /* some sanity checking: below 100MHz is invalid */
if (d.getFrequency() < 10000)
break;
if ( m_chid_current.dvbnamespace.get() != -1 &&
((ns.get() ^ m_chid_current.dvbnamespace.get()) & 0xFFFF0000))
- eDebug("dropping this transponder, it's on another satellite.");
+ SCAN_eDebug("dropping this transponder, it's on another satellite.");
else
{
addChannelToScan(
These are the reasons for adding the transponder
here, and not before.
*/
-
+
if (!m_chid_current)
eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
else
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());
+ m_last_service = m_new_services.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();
}
-void eDVBScan::insertInto(iDVBChannelList *db)
+void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
{
+ if (m_flags & scanRemoveServices)
+ {
+ bool clearTerrestrial=false;
+ bool clearCable=false;
+ std::set<unsigned int> scanned_sat_positions;
+
+ std::list<ePtr<iDVBFrontendParameters> >::iterator it(m_ch_scanned.begin());
+ for (;it != m_ch_scanned.end(); ++it)
+ {
+ int system;
+ (*it)->getSystem(system);
+ switch(system)
+ {
+ case iDVBFrontend::feSatellite:
+ {
+ eDVBFrontendParametersSatellite sat_parm;
+ (*it)->getDVBS(sat_parm);
+ scanned_sat_positions.insert(sat_parm.orbital_position);
+ break;
+ }
+ case iDVBFrontend::feTerrestrial:
+ {
+ clearTerrestrial=true;
+ break;
+ }
+ case iDVBFrontend::feCable:
+ {
+ clearCable=true;
+ break;
+ }
+ }
+ }
+
+ for (it=m_ch_unavailable.begin();it != m_ch_unavailable.end(); ++it)
+ {
+ int system;
+ (*it)->getSystem(system);
+ switch(system)
+ {
+ case iDVBFrontend::feSatellite:
+ {
+ eDVBFrontendParametersSatellite sat_parm;
+ (*it)->getDVBS(sat_parm);
+ scanned_sat_positions.insert(sat_parm.orbital_position);
+ break;
+ }
+ case iDVBFrontend::feTerrestrial:
+ {
+ clearTerrestrial=true;
+ break;
+ }
+ case iDVBFrontend::feCable:
+ {
+ clearCable=true;
+ break;
+ }
+ }
+ }
+
+ if (clearTerrestrial)
+ {
+ eDVBChannelID chid;
+ chid.dvbnamespace=0xEEEE0000;
+ db->removeServices(chid);
+ }
+ if (clearCable)
+ {
+ eDVBChannelID chid;
+ chid.dvbnamespace=0xFFFF0000;
+ db->removeServices(chid);
+ }
+ for (std::set<unsigned int>::iterator x(scanned_sat_positions.begin()); x != scanned_sat_positions.end(); ++x)
+ {
+ eDVBChannelID chid;
+ if (m_flags & scanDontRemoveFeeds)
+ chid.dvbnamespace = eDVBNamespace((*x)<<16);
+// eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
+ db->removeServices(chid, *x);
+ }
+ }
+
for (std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> >::const_iterator
ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch)
db->addChannelToList(ch->first, ch->second);
{
ePtr<eDVBService> dvb_service;
if (!db->getService(service->first, dvb_service))
- *dvb_service = *service->second;
+ {
+ if (dvb_service->m_flags & eDVBService::dxNoSDT)
+ continue;
+ if (!(dvb_service->m_flags & eDVBService::dxHoldName))
+ {
+ dvb_service->m_service_name = service->second->m_service_name;
+ dvb_service->m_service_name_sort = service->second->m_service_name_sort;
+ }
+ dvb_service->m_provider_name = service->second->m_provider_name;
+
+ if (!dontRemoveOldFlags) // do not remove new found flags when not wished
+ dvb_service->m_flags &= ~eDVBService::dxNewFound;
+ }
else
+ {
db->addService(service->first, service->second);
+ service->second->m_flags |= eDVBService::dxNewFound;
+ }
}
}
SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str());
break;
}
+/*
case CA_IDENTIFIER_DESCRIPTOR:
{
CaIdentifierDescriptor &d = (CaIdentifierDescriptor&)**desc;
SCAN_eDebug("");
break;
}
+*/
default:
SCAN_eDebug("descr<%x>", (*desc)->getTag());
break;
}
}
- m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
+ std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
+
+ if (i.second)
+ {
+ m_last_service = i.first;
+ m_event(evtNewService);
+ }
}
return 0;
}
transponders_total = m_ch_toScan.size() + transponders_done;
services = m_new_services.size();
}
+
+void eDVBScan::getLastServiceName(std::string &last_service_name)
+{
+ if (m_last_service == m_new_services.end())
+ last_service_name = "";
+ else
+ last_service_name = m_last_service->second->m_service_name;
+}