1 #include <lib/dvb/idvb.h>
2 #include <dvbsi++/descriptor_tag.h>
3 #include <dvbsi++/service_descriptor.h>
4 #include <dvbsi++/satellite_delivery_system_descriptor.h>
5 #include <dvbsi++/terrestrial_delivery_system_descriptor.h>
6 #include <dvbsi++/cable_delivery_system_descriptor.h>
7 #include <dvbsi++/ca_identifier_descriptor.h>
8 #include <lib/dvb/specs.h>
9 #include <lib/dvb/esection.h>
10 #include <lib/dvb/scan.h>
11 #include <lib/dvb/frontend.h>
12 #include <lib/base/eerror.h>
13 #include <lib/base/estring.h>
16 static bool scan_debug;
17 #define SCAN_eDebug(x...) do { if (scan_debug) eDebug(x); } while(0)
18 #define SCAN_eDebugNoNewLine(x...) do { if (scan_debug) eDebugNoNewLine(x); } while(0)
22 eDVBScan::eDVBScan(iDVBChannel *channel, bool usePAT, bool debug)
23 :m_channel(channel), m_channel_state(iDVBChannel::state_idle)
24 ,m_ready(0), m_ready_all(usePAT ? (readySDT|readyPAT) : readySDT)
25 ,m_pmt_running(false), m_abort_current_pmt(false), m_flags(0), m_usePAT(usePAT)
28 if (m_channel->getDemux(m_demux))
29 SCAN_eDebug("scan: failed to allocate demux!");
30 m_channel->connectStateChange(slot(*this, &eDVBScan::stateChange), m_stateChanged_connection);
37 int eDVBScan::isValidONIDTSID(int orbital_position, eOriginalNetworkID onid, eTransportStreamID tsid)
45 return orbital_position == 192;
47 return tsid != 0x00B0;
49 return abs(orbital_position-282) < 6;
51 return onid.get() < 0xFF00;
55 eDVBNamespace eDVBScan::buildNamespace(eOriginalNetworkID onid, eTransportStreamID tsid, unsigned long hash)
57 // on valid ONIDs, ignore frequency ("sub network") part
58 if (isValidONIDTSID((hash >> 16) & 0xFFFF, onid, tsid))
60 return eDVBNamespace(hash);
63 void eDVBScan::stateChange(iDVBChannel *ch)
66 if (ch->getState(state))
68 if (m_channel_state == state)
71 if (state == iDVBChannel::state_ok)
74 m_channel_state = state;
75 } else if (state == iDVBChannel::state_failed)
77 m_ch_unavailable.push_back(m_ch_current);
80 /* unavailable will timeout, anyway. */
83 RESULT eDVBScan::nextChannel()
85 ePtr<iDVBFrontend> fe;
87 m_SDT = 0; m_PAT = 0; m_BAT = 0; m_NIT = 0, m_PMT = 0;
91 m_pat_tsid = eTransportStreamID();
93 /* check what we need */
94 m_ready_all = readySDT;
96 if (m_flags & scanNetworkSearch)
97 m_ready_all |= readyNIT;
99 if (m_flags & scanSearchBAT)
100 m_ready_all |= readyBAT;
103 m_ready_all |= readyPAT;
105 if (m_ch_toScan.empty())
107 SCAN_eDebug("no channels left to scan.");
108 SCAN_eDebug("%d channels scanned, %d were unavailable.",
109 m_ch_scanned.size(), m_ch_unavailable.size());
110 SCAN_eDebug("%d channels in database.", m_new_channels.size());
115 m_ch_current = m_ch_toScan.front();
117 m_ch_toScan.pop_front();
119 if (m_channel->getFrontend(fe))
125 m_chid_current = eDVBChannelID();
127 m_channel_state = iDVBChannel::state_idle;
129 if (fe->tune(*m_ch_current))
130 return nextChannel();
136 RESULT eDVBScan::startFilter()
141 /* only start required filters filter */
143 if (m_ready_all & readyPAT)
144 startSDT = m_ready & readyPAT;
147 if (startSDT && (m_ready_all & readySDT))
149 m_SDT = new eTable<ServiceDescriptionSection>();
151 if (m_ready & readyPAT && m_ready & validPAT)
153 std::vector<ProgramAssociationSection*>::const_iterator i =
154 m_PAT->getSections().begin();
155 assert(i != m_PAT->getSections().end());
156 tsid = (*i)->getTableIdExtension(); // in PAT this is the transport stream id
157 m_pat_tsid = eTransportStreamID(tsid);
158 for (; i != m_PAT->getSections().end(); ++i)
160 const ProgramAssociationSection &pat = **i;
161 ProgramAssociationConstIterator program = pat.getPrograms()->begin();
162 for (; program != pat.getPrograms()->end(); ++program)
163 m_pmts_to_read.insert(std::pair<unsigned short, service>((*program)->getProgramNumber(), service((*program)->getProgramMapPid())));
165 m_PMT = new eTable<ProgramMapSection>();
166 CONNECT(m_PMT->tableReady, eDVBScan::PMTready);
169 // KabelBW HACK ... on 618Mhz and 626Mhz the transport stream id in PAT and SDT is different
172 m_ch_current->getSystem(type);
173 if (type == iDVBFrontend::feCable)
175 eDVBFrontendParametersCable parm;
176 m_ch_current->getDVBC(parm);
177 if ((tsid == 0x00d7 && abs(parm.frequency-618000) < 2000) ||
178 (tsid == 0x00d8 && abs(parm.frequency-626000) < 2000))
185 if (m_SDT->start(m_demux, eDVBSDTSpec()))
188 else if (m_SDT->start(m_demux, eDVBSDTSpec(tsid, true)))
190 CONNECT(m_SDT->tableReady, eDVBScan::SDTready);
193 if (!(m_ready & readyPAT))
196 if (m_ready_all & readyPAT)
198 m_PAT = new eTable<ProgramAssociationSection>();
199 if (m_PAT->start(m_demux, eDVBPATSpec()))
201 CONNECT(m_PAT->tableReady, eDVBScan::PATready);
205 if (m_ready_all & readyNIT)
207 m_NIT = new eTable<NetworkInformationSection>();
208 if (m_NIT->start(m_demux, eDVBNITSpec()))
210 CONNECT(m_NIT->tableReady, eDVBScan::NITready);
214 if (m_ready_all & readyBAT)
216 m_BAT = new eTable<BouquetAssociationSection>();
217 if (m_BAT->start(m_demux, eDVBBATSpec()))
219 CONNECT(m_BAT->tableReady, eDVBScan::BATready);
226 void eDVBScan::SDTready(int err)
228 SCAN_eDebug("got sdt %d", err);
235 void eDVBScan::NITready(int err)
237 SCAN_eDebug("got nit, err %d", err);
244 void eDVBScan::BATready(int err)
246 SCAN_eDebug("got bat");
253 void eDVBScan::PATready(int err)
255 SCAN_eDebug("got pat");
259 startFilter(); // for starting the SDT filter
262 void eDVBScan::PMTready(int err)
264 SCAN_eDebug("got pmt %d", err);
267 bool scrambled = false;
268 bool have_audio = false;
269 bool have_video = false;
270 unsigned short pcrpid = 0xFFFF;
271 std::vector<ProgramMapSection*>::const_iterator i;
272 for (i = m_PMT->getSections().begin(); i != m_PMT->getSections().end(); ++i)
274 const ProgramMapSection &pmt = **i;
275 if (pcrpid == 0xFFFF)
276 pcrpid = pmt.getPcrPid();
278 eDebug("already have a pcrpid %04x %04x", pcrpid, pmt.getPcrPid());
279 ElementaryStreamInfoConstIterator es;
280 for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
282 int isaudio = 0, isvideo = 0, is_scrambled = 0;
283 switch ((*es)->getType())
285 case 0x1b: // AVC Video Stream (MPEG4 H264)
286 case 0x01: // MPEG 1 video
287 case 0x02: // MPEG 2 video
289 //break; fall through !!!
290 case 0x03: // MPEG 1 audio
291 case 0x04: // MPEG 2 audio:
294 //break; fall through !!!
295 case 0x06: // PES Private
296 case 0x81: // user private
297 /* PES private can contain AC-3, DTS or lots of other stuff.
298 check descriptors to get the exact type. */
299 for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
300 desc != (*es)->getDescriptors()->end(); ++desc)
302 switch ((*desc)->getTag())
313 case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
315 /* libdvbsi++ doesn't yet support this descriptor type, so work around. */
316 if ((*desc)->getLength() != 4)
318 unsigned char descr[6];
319 (*desc)->writeToBuffer(descr);
320 int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]);
321 switch (format_identifier)
343 for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
344 desc != pmt.getDescriptors()->end(); ++desc)
346 if ((*desc)->getTag() == CA_DESCRIPTOR)
350 m_pmt_in_progress->second.scrambled = scrambled;
352 m_pmt_in_progress->second.serviceType = 1;
353 else if ( have_audio )
354 m_pmt_in_progress->second.serviceType = 2;
356 m_pmt_in_progress->second.serviceType = 100;
358 if (err == -2) // aborted in sdt progress
359 m_pmts_to_read.erase(m_pmt_in_progress++);
360 else if (m_pmt_running)
364 m_pmt_in_progress = m_pmts_to_read.begin();
365 m_pmt_running = true;
368 if (m_pmt_in_progress != m_pmts_to_read.end())
369 m_PMT->start(m_demux, eDVBPMTSpec(m_pmt_in_progress->second.pmtPid, m_pmt_in_progress->first));
372 m_pmt_running = false;
378 void eDVBScan::addKnownGoodChannel(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
380 /* add it to the list of known channels. */
382 m_new_channels.insert(std::pair<eDVBChannelID,ePtr<iDVBFrontendParameters> >(chid, feparm));
385 void eDVBScan::addChannelToScan(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
387 /* check if we don't already have that channel ... */
390 feparm->getSystem(type);
394 case iDVBFrontend::feSatellite:
396 eDVBFrontendParametersSatellite parm;
397 feparm->getDVBS(parm);
398 eDebug("try to add %d %d %d %d %d %d",
399 parm.orbital_position, parm.frequency, parm.symbol_rate, parm.polarisation, parm.fec, parm.modulation);
402 case iDVBFrontend::feCable:
404 eDVBFrontendParametersCable parm;
405 feparm->getDVBC(parm);
406 eDebug("try to add %d %d %d %d",
407 parm.frequency, parm.symbol_rate, parm.modulation, parm.fec_inner);
410 case iDVBFrontend::feTerrestrial:
412 eDVBFrontendParametersTerrestrial parm;
413 feparm->getDVBT(parm);
414 eDebug("try to add %d %d %d %d %d %d %d %d",
415 parm.frequency, parm.modulation, parm.transmission_mode, parm.hierarchy,
416 parm.guard_interval, parm.code_rate_LP, parm.code_rate_HP, parm.bandwidth);
422 /* ... in the list of channels to scan */
423 for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
425 if (sameChannel(*i, feparm))
429 *i = feparm; // update
434 eDebug("remove dupe");
435 m_ch_toScan.erase(i++);
445 eDebug("already in todo list");
449 /* ... in the list of successfully scanned channels */
450 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_scanned.begin()); i != m_ch_scanned.end(); ++i)
451 if (sameChannel(*i, feparm))
453 eDebug("successfully scanned");
457 /* ... in the list of unavailable channels */
458 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_unavailable.begin()); i != m_ch_unavailable.end(); ++i)
459 if (sameChannel(*i, feparm, true))
461 eDebug("scanned but not available");
465 /* ... on the current channel */
466 if (sameChannel(m_ch_current, feparm))
468 eDebug("is current");
472 eDebug("really add");
473 /* otherwise, add it to the todo list. */
474 m_ch_toScan.push_front(feparm); // better.. then the rotor not turning wild from east to west :)
477 int eDVBScan::sameChannel(iDVBFrontendParameters *ch1, iDVBFrontendParameters *ch2, bool exact) const
480 if (ch1->calculateDifference(ch2, diff, exact))
482 if (diff < 4000) // more than 4mhz difference?
487 void eDVBScan::channelDone()
489 if (m_ready & validSDT && (!(m_flags & scanOnlyFree) || !m_pmt_running))
491 unsigned long hash = 0;
493 // m_ch_current is not set, when eDVBScan is just used for a SDT update
496 unsigned int channelFlags;
497 m_channel->getCurrentFrontendParameters(m_ch_current);
498 m_ch_current->getFlags(channelFlags);
499 if (channelFlags & iDVBFrontendParameters::flagOnlyFree)
500 m_flags |= scanOnlyFree;
503 m_ch_current->getHash(hash);
505 eDVBNamespace dvbnamespace = buildNamespace(
506 (**m_SDT->getSections().begin()).getOriginalNetworkId(),
507 (**m_SDT->getSections().begin()).getTransportStreamId(),
510 SCAN_eDebug("SDT: ");
511 std::vector<ServiceDescriptionSection*>::const_iterator i;
512 for (i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
513 processSDT(dvbnamespace, **i);
514 m_ready &= ~validSDT;
517 if (m_ready & validNIT)
521 std::list<ePtr<iDVBFrontendParameters> > m_ch_toScan_backup;
522 m_ch_current->getSystem(system);
523 SCAN_eDebug("dumping NIT");
524 if (m_flags & clearToScanOnFirstNIT)
526 m_ch_toScan_backup = m_ch_toScan;
529 std::vector<NetworkInformationSection*>::const_iterator i;
530 for (i = m_NIT->getSections().begin(); i != m_NIT->getSections().end(); ++i)
532 const TransportStreamInfoList &tsinfovec = *(*i)->getTsInfo();
534 for (TransportStreamInfoConstIterator tsinfo(tsinfovec.begin());
535 tsinfo != tsinfovec.end(); ++tsinfo)
537 SCAN_eDebug("TSID: %04x ONID: %04x", (*tsinfo)->getTransportStreamId(),
538 (*tsinfo)->getOriginalNetworkId());
540 eOriginalNetworkID onid = (*tsinfo)->getOriginalNetworkId();
541 eTransportStreamID tsid = (*tsinfo)->getTransportStreamId();
543 for (DescriptorConstIterator desc = (*tsinfo)->getDescriptors()->begin();
544 desc != (*tsinfo)->getDescriptors()->end(); ++desc)
546 switch ((*desc)->getTag())
548 case CABLE_DELIVERY_SYSTEM_DESCRIPTOR:
550 if (system != iDVBFrontend::feCable)
551 break; // when current locked transponder is no cable transponder ignore this descriptor
552 CableDeliverySystemDescriptor &d = (CableDeliverySystemDescriptor&)**desc;
553 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
554 eDVBFrontendParametersCable cable;
556 feparm->setDVBC(cable);
558 unsigned long hash=0;
559 feparm->getHash(hash);
560 eDVBNamespace ns = buildNamespace(onid, tsid, hash);
563 eDVBChannelID(ns, tsid, onid),
567 case TERRESTRIAL_DELIVERY_SYSTEM_DESCRIPTOR:
569 if (system != iDVBFrontend::feTerrestrial)
570 break; // when current locked transponder is no terrestrial transponder ignore this descriptor
571 TerrestrialDeliverySystemDescriptor &d = (TerrestrialDeliverySystemDescriptor&)**desc;
572 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
573 eDVBFrontendParametersTerrestrial terr;
575 feparm->setDVBT(terr);
577 unsigned long hash=0;
578 feparm->getHash(hash);
579 eDVBNamespace ns = buildNamespace(onid, tsid, hash);
582 eDVBChannelID(ns, tsid, onid),
586 case SATELLITE_DELIVERY_SYSTEM_DESCRIPTOR:
588 if (system != iDVBFrontend::feSatellite)
589 break; // when current locked transponder is no satellite transponder ignore this descriptor
591 SatelliteDeliverySystemDescriptor &d = (SatelliteDeliverySystemDescriptor&)**desc;
592 if (d.getFrequency() < 10000)
595 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
596 eDVBFrontendParametersSatellite sat;
599 eDVBFrontendParametersSatellite p;
600 m_ch_current->getDVBS(p);
602 if ( abs(p.orbital_position - sat.orbital_position) < 5 )
603 sat.orbital_position = p.orbital_position;
605 if ( abs(abs(3600 - p.orbital_position) - sat.orbital_position) < 5 )
607 eDebug("found transponder with incorrect west/east flag ... correct this");
608 sat.orbital_position = p.orbital_position;
611 feparm->setDVBS(sat);
613 if ( p.orbital_position != sat.orbital_position)
614 SCAN_eDebug("dropping this transponder, it's on another satellite.");
617 unsigned long hash=0;
618 feparm->getHash(hash);
620 eDVBChannelID(buildNamespace(onid, tsid, hash), tsid, onid),
626 SCAN_eDebug("descr<%x>", (*desc)->getTag());
634 /* a pitfall is to have the clearToScanOnFirstNIT-flag set, and having channels which have
635 no or invalid NIT. this code will not erase the toScan list unless at least one valid entry
638 This is not a perfect solution, as the channel could contain a partial NIT. Life's bad.
640 if (m_flags & clearToScanOnFirstNIT)
642 if (m_ch_toScan.empty())
644 eWarning("clearToScanOnFirstNIT was set, but NIT is invalid. Refusing to stop scan.");
645 m_ch_toScan = m_ch_toScan_backup;
647 m_flags &= ~clearToScanOnFirstNIT;
649 m_ready &= ~validNIT;
652 if (m_pmt_running || (m_ready & m_ready_all) != m_ready_all)
654 if (m_abort_current_pmt)
656 m_abort_current_pmt = false;
662 SCAN_eDebug("channel done!");
664 /* if we had services on this channel, we declare
665 this channels as "known good". add it.
667 (TODO: not yet implemented)
668 a NIT entry could have possible overridden
669 our frontend data with more exact data.
671 (TODO: not yet implemented)
672 the tuning process could have lead to more
673 exact data than the user entered.
675 The channel id was probably corrected
676 by the data written in the SDT. this is
677 important, as "initial transponder lists"
678 usually don't have valid CHIDs (and that's
681 These are the reasons for adding the transponder
682 here, and not before.
685 for (m_pmt_in_progress = m_pmts_to_read.begin(); m_pmt_in_progress != m_pmts_to_read.end();)
688 eServiceReferenceDVB ref;
689 ePtr<eDVBService> service = new eDVBService;
693 unsigned long hash = 0;
695 // m_ch_current is not set, when eDVBScan is just used for a SDT update
698 unsigned int channelFlags;
699 m_channel->getCurrentFrontendParameters(m_ch_current);
700 m_ch_current->getFlags(channelFlags);
701 if (channelFlags & iDVBFrontendParameters::flagOnlyFree)
702 m_flags |= scanOnlyFree;
705 m_ch_current->getHash(hash);
707 m_chid_current = eDVBChannelID(
708 buildNamespace(eOriginalNetworkID(0), m_pat_tsid, hash),
709 m_pat_tsid, eOriginalNetworkID(0));
712 if (m_pmt_in_progress->second.serviceType == 1)
713 SCAN_eDebug("SID %04x is VIDEO", m_pmt_in_progress->first);
714 else if (m_pmt_in_progress->second.serviceType == 2)
715 SCAN_eDebug("SID %04x is AUDIO", m_pmt_in_progress->first);
717 SCAN_eDebug("SID %04x is DATA", m_pmt_in_progress->first);
719 ref.set(m_chid_current);
720 ref.setServiceID(m_pmt_in_progress->first);
721 ref.setServiceType(m_pmt_in_progress->second.serviceType);
723 if (!m_ch_current->getSystem(type))
727 memset(pname, 0, sizeof(pname));
728 memset(sname, 0, sizeof(sname));
731 case iDVBFrontend::feSatellite:
733 eDVBFrontendParametersSatellite parm;
734 m_ch_current->getDVBS(parm);
735 snprintf(sname, 255, "%d%c SID 0x%02x",
737 parm.polarisation ? 'V' : 'H',
738 m_pmt_in_progress->first);
739 snprintf(pname, 255, "%s %s %d%c %d.%d°%c",
740 parm.system ? "DVB-S2" : "DVB-S",
741 parm.modulation == 1 ? "QPSK" : "8PSK",
743 parm.polarisation ? 'V' : 'H',
744 parm.orbital_position/10,
745 parm.orbital_position%10,
746 parm.orbital_position > 0 ? 'E' : 'W');
749 case iDVBFrontend::feTerrestrial:
751 eDVBFrontendParametersTerrestrial parm;
752 m_ch_current->getDVBT(parm);
753 snprintf(sname, 255, "%d SID 0x%02x",
755 m_pmt_in_progress->first);
758 case iDVBFrontend::feCable:
760 eDVBFrontendParametersCable parm;
761 m_ch_current->getDVBC(parm);
762 snprintf(sname, 255, "%d SID 0x%02x",
764 m_pmt_in_progress->first);
768 SCAN_eDebug("name '%s', provider_name '%s'", sname, pname);
769 service->m_service_name = convertDVBUTF8(sname);
770 service->genSortName();
771 service->m_provider_name = pname;
774 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
778 m_last_service = i.first;
779 m_event(evtNewService);
781 m_pmts_to_read.erase(m_pmt_in_progress++);
785 eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
787 addKnownGoodChannel(m_chid_current, m_ch_current);
789 m_ch_scanned.push_back(m_ch_current);
791 for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
793 if (sameChannel(*i, m_ch_current))
795 eDebug("remove dupe 2");
796 m_ch_toScan.erase(i++);
805 void eDVBScan::start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags)
809 m_ch_scanned.clear();
810 m_ch_unavailable.clear();
811 m_new_channels.clear();
812 m_new_services.clear();
813 m_last_service = m_new_services.end();
815 for (eSmartPtrList<iDVBFrontendParameters>::const_iterator i(known_transponders.begin()); i != known_transponders.end(); ++i)
818 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator ii(m_ch_toScan.begin()); ii != m_ch_toScan.end(); ++ii)
820 if (sameChannel(*i, *ii, true))
827 m_ch_toScan.push_back(*i);
833 void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
835 if (m_flags & scanRemoveServices)
837 bool clearTerrestrial=false;
838 bool clearCable=false;
839 std::set<unsigned int> scanned_sat_positions;
841 std::list<ePtr<iDVBFrontendParameters> >::iterator it(m_ch_scanned.begin());
842 for (;it != m_ch_scanned.end(); ++it)
844 if (m_flags & scanDontRemoveUnscanned) {
845 eDebug("scanDontRemoveUnscanned!");
846 db->removeServices(&(*(*it)));
851 (*it)->getSystem(system);
854 case iDVBFrontend::feSatellite:
856 eDVBFrontendParametersSatellite sat_parm;
857 (*it)->getDVBS(sat_parm);
858 scanned_sat_positions.insert(sat_parm.orbital_position);
861 case iDVBFrontend::feTerrestrial:
863 clearTerrestrial=true;
866 case iDVBFrontend::feCable:
875 for (it=m_ch_unavailable.begin();it != m_ch_unavailable.end(); ++it)
877 if (m_flags & scanDontRemoveUnscanned)
878 db->removeServices(&(*(*it)));
882 (*it)->getSystem(system);
885 case iDVBFrontend::feSatellite:
887 eDVBFrontendParametersSatellite sat_parm;
888 (*it)->getDVBS(sat_parm);
889 scanned_sat_positions.insert(sat_parm.orbital_position);
892 case iDVBFrontend::feTerrestrial:
894 clearTerrestrial=true;
897 case iDVBFrontend::feCable:
906 if (clearTerrestrial)
909 chid.dvbnamespace=0xEEEE0000;
910 db->removeServices(chid);
915 chid.dvbnamespace=0xFFFF0000;
916 db->removeServices(chid);
918 for (std::set<unsigned int>::iterator x(scanned_sat_positions.begin()); x != scanned_sat_positions.end(); ++x)
921 if (m_flags & scanDontRemoveFeeds)
922 chid.dvbnamespace = eDVBNamespace((*x)<<16);
923 // eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
924 db->removeServices(chid, *x);
928 for (std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> >::const_iterator
929 ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch)
931 if (m_flags & scanOnlyFree)
933 eDVBFrontendParameters *ptr = (eDVBFrontendParameters*)&(*ch->second);
934 ptr->setFlags(iDVBFrontendParameters::flagOnlyFree);
936 db->addChannelToList(ch->first, ch->second);
939 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::const_iterator
940 service(m_new_services.begin()); service != m_new_services.end(); ++service)
942 ePtr<eDVBService> dvb_service;
943 if (!db->getService(service->first, dvb_service))
945 if (dvb_service->m_flags & eDVBService::dxNoSDT)
947 if (!(dvb_service->m_flags & eDVBService::dxHoldName))
949 dvb_service->m_service_name = service->second->m_service_name;
950 dvb_service->m_service_name_sort = service->second->m_service_name_sort;
952 dvb_service->m_provider_name = service->second->m_provider_name;
953 if (service->second->m_ca.size())
954 dvb_service->m_ca = service->second->m_ca;
955 if (!dontRemoveOldFlags) // do not remove new found flags when not wished
956 dvb_service->m_flags &= ~eDVBService::dxNewFound;
960 db->addService(service->first, service->second);
961 if (!(m_flags & scanRemoveServices))
962 service->second->m_flags |= eDVBService::dxNewFound;
967 RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescriptionSection &sdt)
969 const ServiceDescriptionList &services = *sdt.getDescriptions();
970 SCAN_eDebug("ONID: %04x", sdt.getOriginalNetworkId());
971 eDVBChannelID chid(dvbnamespace, sdt.getTransportStreamId(), sdt.getOriginalNetworkId());
973 /* save correct CHID for this channel */
974 m_chid_current = chid;
976 for (ServiceDescriptionConstIterator s(services.begin()); s != services.end(); ++s)
978 unsigned short service_id = (*s)->getServiceId();
979 SCAN_eDebugNoNewLine("SID %04x: ", service_id);
982 if (m_flags & scanOnlyFree)
984 std::map<unsigned short, service>::iterator it =
985 m_pmts_to_read.find(service_id);
986 if (it != m_pmts_to_read.end())
988 if (it->second.scrambled)
990 SCAN_eDebug("is scrambled!");
995 SCAN_eDebug("not found in PAT.. so we assume it is scrambled!!");
1000 eServiceReferenceDVB ref;
1001 ePtr<eDVBService> service = new eDVBService;
1004 ref.setServiceID(service_id);
1006 for (DescriptorConstIterator desc = (*s)->getDescriptors()->begin();
1007 desc != (*s)->getDescriptors()->end(); ++desc)
1009 switch ((*desc)->getTag())
1011 case SERVICE_DESCRIPTOR:
1013 ServiceDescriptor &d = (ServiceDescriptor&)**desc;
1014 ref.setServiceType(d.getServiceType());
1015 service->m_service_name = convertDVBUTF8(d.getServiceName());
1016 service->genSortName();
1018 service->m_provider_name = convertDVBUTF8(d.getServiceProviderName());
1019 SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str());
1022 case CA_IDENTIFIER_DESCRIPTOR:
1024 CaIdentifierDescriptor &d = (CaIdentifierDescriptor&)**desc;
1025 const CaSystemIdList &caids = *d.getCaSystemIds();
1026 SCAN_eDebugNoNewLine("CA ");
1027 for (CaSystemIdList::const_iterator i(caids.begin()); i != caids.end(); ++i)
1029 SCAN_eDebugNoNewLine("%04x ", *i);
1030 service->m_ca.push_front(*i);
1036 SCAN_eDebug("descr<%x>", (*desc)->getTag());
1041 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
1045 m_last_service = i.first;
1046 m_event(evtNewService);
1049 if (m_pmt_running && m_pmt_in_progress->first == service_id)
1050 m_abort_current_pmt = true;
1052 m_pmts_to_read.erase(service_id);
1058 RESULT eDVBScan::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1060 connection = new eConnection(this, m_event.connect(event));
1064 void eDVBScan::getStats(int &transponders_done, int &transponders_total, int &services)
1066 transponders_done = m_ch_scanned.size() + m_ch_unavailable.size();
1067 transponders_total = m_ch_toScan.size() + transponders_done;
1068 services = m_new_services.size();
1071 void eDVBScan::getLastServiceName(std::string &last_service_name)
1073 if (m_last_service == m_new_services.end())
1074 last_service_name = "";
1076 last_service_name = m_last_service->second->m_service_name;
1079 RESULT eDVBScan::getFrontend(ePtr<iDVBFrontend> &fe)
1082 return m_channel->getFrontend(fe);
1087 RESULT eDVBScan::getCurrentTransponder(ePtr<iDVBFrontendParameters> &tp)