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 #define SCAN_eDebug(x...) do { if (m_scan_debug) eDebug(x); } while(0)
17 #define SCAN_eDebugNoNewLine(x...) do { if (m_scan_debug) eDebugNoNewLine(x); } while(0)
21 eDVBScan::eDVBScan(iDVBChannel *channel, bool usePAT, bool debug)
22 :m_channel(channel), m_channel_state(iDVBChannel::state_idle)
23 ,m_ready(0), m_ready_all(usePAT ? (readySDT|readyPAT) : readySDT)
24 ,m_pmt_running(false), m_abort_current_pmt(false), m_flags(0)
25 ,m_usePAT(usePAT), m_scan_debug(debug)
27 if (m_channel->getDemux(m_demux))
28 SCAN_eDebug("scan: failed to allocate demux!");
29 m_channel->connectStateChange(slot(*this, &eDVBScan::stateChange), m_stateChanged_connection);
36 int eDVBScan::isValidONIDTSID(int orbital_position, eOriginalNetworkID onid, eTransportStreamID tsid)
44 return orbital_position == 192;
46 return tsid != 0x00B0;
48 return abs(orbital_position-282) < 6;
50 return onid.get() < 0xFF00;
54 eDVBNamespace eDVBScan::buildNamespace(eOriginalNetworkID onid, eTransportStreamID tsid, unsigned long hash)
56 // on valid ONIDs, ignore frequency ("sub network") part
57 if (isValidONIDTSID((hash >> 16) & 0xFFFF, onid, tsid))
59 return eDVBNamespace(hash);
62 void eDVBScan::stateChange(iDVBChannel *ch)
65 if (ch->getState(state))
67 if (m_channel_state == state)
70 if (state == iDVBChannel::state_ok)
73 m_channel_state = state;
74 } else if (state == iDVBChannel::state_failed)
76 m_ch_unavailable.push_back(m_ch_current);
79 /* unavailable will timeout, anyway. */
82 RESULT eDVBScan::nextChannel()
84 ePtr<iDVBFrontend> fe;
86 m_SDT = 0; m_PAT = 0; m_BAT = 0; m_NIT = 0, m_PMT = 0;
90 m_pat_tsid = eTransportStreamID();
92 /* check what we need */
93 m_ready_all = readySDT;
95 if (m_flags & scanNetworkSearch)
96 m_ready_all |= readyNIT;
98 if (m_flags & scanSearchBAT)
99 m_ready_all |= readyBAT;
102 m_ready_all |= readyPAT;
104 if (m_ch_toScan.empty())
106 SCAN_eDebug("no channels left to scan.");
107 SCAN_eDebug("%d channels scanned, %d were unavailable.",
108 m_ch_scanned.size(), m_ch_unavailable.size());
109 SCAN_eDebug("%d channels in database.", m_new_channels.size());
114 m_ch_current = m_ch_toScan.front();
116 m_ch_toScan.pop_front();
118 if (m_channel->getFrontend(fe))
124 m_chid_current = eDVBChannelID();
126 m_channel_state = iDVBChannel::state_idle;
128 if (fe->tune(*m_ch_current))
129 return nextChannel();
135 RESULT eDVBScan::startFilter()
140 /* only start required filters filter */
142 if (m_ready_all & readyPAT)
143 startSDT = m_ready & readyPAT;
145 // m_ch_current is not set, when eDVBScan is just used for a SDT update
148 unsigned int channelFlags;
149 m_channel->getCurrentFrontendParameters(m_ch_current);
150 m_ch_current->getFlags(channelFlags);
151 if (channelFlags & iDVBFrontendParameters::flagOnlyFree)
152 m_flags |= scanOnlyFree;
156 if (startSDT && (m_ready_all & readySDT))
158 m_SDT = new eTable<ServiceDescriptionSection>(m_scan_debug);
160 if (m_ready & readyPAT && m_ready & validPAT)
162 std::vector<ProgramAssociationSection*>::const_iterator i =
163 m_PAT->getSections().begin();
164 assert(i != m_PAT->getSections().end());
165 tsid = (*i)->getTableIdExtension(); // in PAT this is the transport stream id
166 m_pat_tsid = eTransportStreamID(tsid);
167 for (; i != m_PAT->getSections().end(); ++i)
169 const ProgramAssociationSection &pat = **i;
170 ProgramAssociationConstIterator program = pat.getPrograms()->begin();
171 for (; program != pat.getPrograms()->end(); ++program)
172 m_pmts_to_read.insert(std::pair<unsigned short, service>((*program)->getProgramNumber(), service((*program)->getProgramMapPid())));
174 m_PMT = new eTable<ProgramMapSection>(m_scan_debug);
175 CONNECT(m_PMT->tableReady, eDVBScan::PMTready);
177 // KabelBW HACK ... on 618Mhz and 626Mhz the transport stream id in PAT and SDT is different
181 m_ch_current->getSystem(type);
182 if (type == iDVBFrontend::feCable)
184 eDVBFrontendParametersCable parm;
185 m_ch_current->getDVBC(parm);
186 if ((tsid == 0x00d7 && abs(parm.frequency-618000) < 2000) ||
187 (tsid == 0x00d8 && abs(parm.frequency-626000) < 2000))
194 if (m_SDT->start(m_demux, eDVBSDTSpec()))
197 else if (m_SDT->start(m_demux, eDVBSDTSpec(tsid, true)))
199 CONNECT(m_SDT->tableReady, eDVBScan::SDTready);
202 if (!(m_ready & readyPAT))
205 if (m_ready_all & readyPAT)
207 m_PAT = new eTable<ProgramAssociationSection>(m_scan_debug);
208 if (m_PAT->start(m_demux, eDVBPATSpec(4000)))
210 CONNECT(m_PAT->tableReady, eDVBScan::PATready);
214 if (m_ready_all & readyNIT)
216 m_NIT = new eTable<NetworkInformationSection>(m_scan_debug);
217 if (m_NIT->start(m_demux, eDVBNITSpec()))
219 CONNECT(m_NIT->tableReady, eDVBScan::NITready);
223 if (m_ready_all & readyBAT)
225 m_BAT = new eTable<BouquetAssociationSection>(m_scan_debug);
226 if (m_BAT->start(m_demux, eDVBBATSpec()))
228 CONNECT(m_BAT->tableReady, eDVBScan::BATready);
234 void eDVBScan::SDTready(int err)
236 SCAN_eDebug("got sdt %d", err);
243 void eDVBScan::NITready(int err)
245 SCAN_eDebug("got nit, err %d", err);
252 void eDVBScan::BATready(int err)
254 SCAN_eDebug("got bat");
261 void eDVBScan::PATready(int err)
263 SCAN_eDebug("got pat");
267 startFilter(); // for starting the SDT filter
270 void eDVBScan::PMTready(int err)
272 SCAN_eDebug("got pmt %d", err);
275 bool scrambled = false;
276 bool have_audio = false;
277 bool have_video = false;
278 unsigned short pcrpid = 0xFFFF;
279 std::vector<ProgramMapSection*>::const_iterator i;
280 for (i = m_PMT->getSections().begin(); i != m_PMT->getSections().end(); ++i)
282 const ProgramMapSection &pmt = **i;
283 if (pcrpid == 0xFFFF)
284 pcrpid = pmt.getPcrPid();
286 SCAN_eDebug("already have a pcrpid %04x %04x", pcrpid, pmt.getPcrPid());
287 ElementaryStreamInfoConstIterator es;
288 for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
290 int isaudio = 0, isvideo = 0, is_scrambled = 0;
291 switch ((*es)->getType())
293 case 0x1b: // AVC Video Stream (MPEG4 H264)
294 case 0x01: // MPEG 1 video
295 case 0x02: // MPEG 2 video
297 //break; fall through !!!
298 case 0x03: // MPEG 1 audio
299 case 0x04: // MPEG 2 audio:
302 //break; fall through !!!
303 case 0x06: // PES Private
304 case 0x81: // user private
305 /* PES private can contain AC-3, DTS or lots of other stuff.
306 check descriptors to get the exact type. */
307 for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
308 desc != (*es)->getDescriptors()->end(); ++desc)
310 uint8_t tag = (*desc)->getTag();
311 if (!isaudio && !isvideo)
320 case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
322 /* libdvbsi++ doesn't yet support this descriptor type, so work around. */
323 if ((*desc)->getLength() != 4)
325 unsigned char descr[6];
326 (*desc)->writeToBuffer(descr);
327 int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]);
328 switch (format_identifier)
339 if (tag == CA_DESCRIPTOR)
353 for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
354 desc != pmt.getDescriptors()->end(); ++desc)
356 if ((*desc)->getTag() == CA_DESCRIPTOR)
360 m_pmt_in_progress->second.scrambled = scrambled;
362 m_pmt_in_progress->second.serviceType = 1;
363 else if ( have_audio )
364 m_pmt_in_progress->second.serviceType = 2;
366 m_pmt_in_progress->second.serviceType = 100;
368 if (err == -1) // timeout or removed by sdt
369 m_pmts_to_read.erase(m_pmt_in_progress++);
370 else if (m_pmt_running)
374 m_pmt_in_progress = m_pmts_to_read.begin();
375 m_pmt_running = true;
378 if (m_pmt_in_progress != m_pmts_to_read.end())
379 m_PMT->start(m_demux, eDVBPMTSpec(m_pmt_in_progress->second.pmtPid, m_pmt_in_progress->first, 4000));
383 m_pmt_running = false;
389 void eDVBScan::addKnownGoodChannel(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
391 /* add it to the list of known channels. */
393 m_new_channels.insert(std::pair<eDVBChannelID,ePtr<iDVBFrontendParameters> >(chid, feparm));
396 void eDVBScan::addChannelToScan(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
398 /* check if we don't already have that channel ... */
401 feparm->getSystem(type);
405 case iDVBFrontend::feSatellite:
407 eDVBFrontendParametersSatellite parm;
408 feparm->getDVBS(parm);
409 SCAN_eDebug("try to add %d %d %d %d %d %d",
410 parm.orbital_position, parm.frequency, parm.symbol_rate, parm.polarisation, parm.fec, parm.modulation);
413 case iDVBFrontend::feCable:
415 eDVBFrontendParametersCable parm;
416 feparm->getDVBC(parm);
417 SCAN_eDebug("try to add %d %d %d %d",
418 parm.frequency, parm.symbol_rate, parm.modulation, parm.fec_inner);
421 case iDVBFrontend::feTerrestrial:
423 eDVBFrontendParametersTerrestrial parm;
424 feparm->getDVBT(parm);
425 SCAN_eDebug("try to add %d %d %d %d %d %d %d %d",
426 parm.frequency, parm.modulation, parm.transmission_mode, parm.hierarchy,
427 parm.guard_interval, parm.code_rate_LP, parm.code_rate_HP, parm.bandwidth);
433 /* ... in the list of channels to scan */
434 for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
436 if (sameChannel(*i, feparm))
440 *i = feparm; // update
441 SCAN_eDebug("update");
445 SCAN_eDebug("remove dupe");
446 m_ch_toScan.erase(i++);
456 SCAN_eDebug("already in todo list");
460 /* ... in the list of successfully scanned channels */
461 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_scanned.begin()); i != m_ch_scanned.end(); ++i)
462 if (sameChannel(*i, feparm))
464 SCAN_eDebug("successfully scanned");
468 /* ... in the list of unavailable channels */
469 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_unavailable.begin()); i != m_ch_unavailable.end(); ++i)
470 if (sameChannel(*i, feparm, true))
472 SCAN_eDebug("scanned but not available");
476 /* ... on the current channel */
477 if (sameChannel(m_ch_current, feparm))
479 SCAN_eDebug("is current");
483 SCAN_eDebug("really add");
484 /* otherwise, add it to the todo list. */
485 m_ch_toScan.push_front(feparm); // better.. then the rotor not turning wild from east to west :)
488 int eDVBScan::sameChannel(iDVBFrontendParameters *ch1, iDVBFrontendParameters *ch2, bool exact) const
491 if (ch1->calculateDifference(ch2, diff, exact))
493 if (diff < 4000) // more than 4mhz difference?
498 void eDVBScan::channelDone()
500 if (m_ready & validSDT && (!(m_flags & scanOnlyFree) || !m_pmt_running))
502 unsigned long hash = 0;
504 m_ch_current->getHash(hash);
506 eDVBNamespace dvbnamespace = buildNamespace(
507 (**m_SDT->getSections().begin()).getOriginalNetworkId(),
508 (**m_SDT->getSections().begin()).getTransportStreamId(),
511 SCAN_eDebug("SDT: ");
512 std::vector<ServiceDescriptionSection*>::const_iterator i;
513 for (i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
514 processSDT(dvbnamespace, **i);
515 m_ready &= ~validSDT;
518 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 SCAN_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->getHash(hash);
697 m_chid_current = eDVBChannelID(
698 buildNamespace(eOriginalNetworkID(0), m_pat_tsid, hash),
699 m_pat_tsid, eOriginalNetworkID(0));
702 if (m_pmt_in_progress->second.serviceType == 1)
703 SCAN_eDebug("SID %04x is VIDEO", m_pmt_in_progress->first);
704 else if (m_pmt_in_progress->second.serviceType == 2)
705 SCAN_eDebug("SID %04x is AUDIO", m_pmt_in_progress->first);
707 SCAN_eDebug("SID %04x is DATA", m_pmt_in_progress->first);
709 ref.set(m_chid_current);
710 ref.setServiceID(m_pmt_in_progress->first);
711 ref.setServiceType(m_pmt_in_progress->second.serviceType);
713 if (!m_ch_current->getSystem(type))
717 memset(pname, 0, sizeof(pname));
718 memset(sname, 0, sizeof(sname));
721 case iDVBFrontend::feSatellite:
723 eDVBFrontendParametersSatellite parm;
724 m_ch_current->getDVBS(parm);
725 snprintf(sname, 255, "%d%c SID 0x%02x",
727 parm.polarisation ? 'V' : 'H',
728 m_pmt_in_progress->first);
729 snprintf(pname, 255, "%s %s %d%c %d.%d°%c",
730 parm.system ? "DVB-S2" : "DVB-S",
731 parm.modulation == 1 ? "QPSK" : "8PSK",
733 parm.polarisation ? 'V' : 'H',
734 parm.orbital_position/10,
735 parm.orbital_position%10,
736 parm.orbital_position > 0 ? 'E' : 'W');
739 case iDVBFrontend::feTerrestrial:
741 eDVBFrontendParametersTerrestrial parm;
742 m_ch_current->getDVBT(parm);
743 snprintf(sname, 255, "%d SID 0x%02x",
745 m_pmt_in_progress->first);
748 case iDVBFrontend::feCable:
750 eDVBFrontendParametersCable parm;
751 m_ch_current->getDVBC(parm);
752 snprintf(sname, 255, "%d SID 0x%02x",
754 m_pmt_in_progress->first);
758 SCAN_eDebug("name '%s', provider_name '%s'", sname, pname);
759 service->m_service_name = convertDVBUTF8(sname);
760 service->genSortName();
761 service->m_provider_name = convertDVBUTF8(pname);
764 if (!(m_flags & scanOnlyFree) || !m_pmt_in_progress->second.scrambled) {
765 SCAN_eDebug("add not scrambled!");
766 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
769 m_last_service = i.first;
770 m_event(evtNewService);
774 SCAN_eDebug("dont add... is scrambled!");
775 m_pmts_to_read.erase(m_pmt_in_progress++);
779 eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
781 addKnownGoodChannel(m_chid_current, m_ch_current);
783 m_ch_scanned.push_back(m_ch_current);
785 for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
787 if (sameChannel(*i, m_ch_current))
789 SCAN_eDebug("remove dupe 2");
790 m_ch_toScan.erase(i++);
799 void eDVBScan::start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags)
803 m_ch_scanned.clear();
804 m_ch_unavailable.clear();
805 m_new_channels.clear();
806 m_new_services.clear();
807 m_last_service = m_new_services.end();
809 for (eSmartPtrList<iDVBFrontendParameters>::const_iterator i(known_transponders.begin()); i != known_transponders.end(); ++i)
812 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator ii(m_ch_toScan.begin()); ii != m_ch_toScan.end(); ++ii)
814 if (sameChannel(*i, *ii, true))
821 m_ch_toScan.push_back(*i);
827 void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
829 if (m_flags & scanRemoveServices)
831 bool clearTerrestrial=false;
832 bool clearCable=false;
833 std::set<unsigned int> scanned_sat_positions;
835 std::list<ePtr<iDVBFrontendParameters> >::iterator it(m_ch_scanned.begin());
836 for (;it != m_ch_scanned.end(); ++it)
838 if (m_flags & scanDontRemoveUnscanned)
839 db->removeServices(&(*(*it)));
843 (*it)->getSystem(system);
846 case iDVBFrontend::feSatellite:
848 eDVBFrontendParametersSatellite sat_parm;
849 (*it)->getDVBS(sat_parm);
850 scanned_sat_positions.insert(sat_parm.orbital_position);
853 case iDVBFrontend::feTerrestrial:
855 clearTerrestrial=true;
858 case iDVBFrontend::feCable:
867 for (it=m_ch_unavailable.begin();it != m_ch_unavailable.end(); ++it)
869 if (m_flags & scanDontRemoveUnscanned)
870 db->removeServices(&(*(*it)));
874 (*it)->getSystem(system);
877 case iDVBFrontend::feSatellite:
879 eDVBFrontendParametersSatellite sat_parm;
880 (*it)->getDVBS(sat_parm);
881 scanned_sat_positions.insert(sat_parm.orbital_position);
884 case iDVBFrontend::feTerrestrial:
886 clearTerrestrial=true;
889 case iDVBFrontend::feCable:
898 if (clearTerrestrial)
901 chid.dvbnamespace=0xEEEE0000;
902 db->removeServices(chid);
907 chid.dvbnamespace=0xFFFF0000;
908 db->removeServices(chid);
910 for (std::set<unsigned int>::iterator x(scanned_sat_positions.begin()); x != scanned_sat_positions.end(); ++x)
913 if (m_flags & scanDontRemoveFeeds)
914 chid.dvbnamespace = eDVBNamespace((*x)<<16);
915 // eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
916 db->removeServices(chid, *x);
920 for (std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> >::const_iterator
921 ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch)
923 if (m_flags & scanOnlyFree)
925 eDVBFrontendParameters *ptr = (eDVBFrontendParameters*)&(*ch->second);
926 ptr->setFlags(iDVBFrontendParameters::flagOnlyFree);
928 db->addChannelToList(ch->first, ch->second);
931 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::const_iterator
932 service(m_new_services.begin()); service != m_new_services.end(); ++service)
934 ePtr<eDVBService> dvb_service;
935 if (!db->getService(service->first, dvb_service))
937 if (dvb_service->m_flags & eDVBService::dxNoSDT)
939 if (!(dvb_service->m_flags & eDVBService::dxHoldName))
941 dvb_service->m_service_name = service->second->m_service_name;
942 dvb_service->m_service_name_sort = service->second->m_service_name_sort;
944 dvb_service->m_provider_name = service->second->m_provider_name;
945 if (service->second->m_ca.size())
946 dvb_service->m_ca = service->second->m_ca;
947 if (!dontRemoveOldFlags) // do not remove new found flags when not wished
948 dvb_service->m_flags &= ~eDVBService::dxNewFound;
952 db->addService(service->first, service->second);
953 if (!(m_flags & scanRemoveServices))
954 service->second->m_flags |= eDVBService::dxNewFound;
959 RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescriptionSection &sdt)
961 const ServiceDescriptionList &services = *sdt.getDescriptions();
962 SCAN_eDebug("ONID: %04x", sdt.getOriginalNetworkId());
963 eDVBChannelID chid(dvbnamespace, sdt.getTransportStreamId(), sdt.getOriginalNetworkId());
965 /* save correct CHID for this channel */
966 m_chid_current = chid;
968 for (ServiceDescriptionConstIterator s(services.begin()); s != services.end(); ++s)
970 unsigned short service_id = (*s)->getServiceId();
971 SCAN_eDebugNoNewLine("SID %04x: ", service_id);
974 if (m_flags & scanOnlyFree)
976 std::map<unsigned short, service>::iterator it =
977 m_pmts_to_read.find(service_id);
978 if (it != m_pmts_to_read.end())
980 if (it->second.scrambled)
982 SCAN_eDebug("is scrambled!");
986 SCAN_eDebug("is free");
989 SCAN_eDebug("not found in PAT.. so we assume it is scrambled!!");
996 eServiceReferenceDVB ref;
997 ePtr<eDVBService> service = new eDVBService;
1000 ref.setServiceID(service_id);
1002 for (DescriptorConstIterator desc = (*s)->getDescriptors()->begin();
1003 desc != (*s)->getDescriptors()->end(); ++desc)
1005 switch ((*desc)->getTag())
1007 case SERVICE_DESCRIPTOR:
1009 ServiceDescriptor &d = (ServiceDescriptor&)**desc;
1010 ref.setServiceType(d.getServiceType());
1011 service->m_service_name = convertDVBUTF8(d.getServiceName());
1012 service->genSortName();
1014 service->m_provider_name = convertDVBUTF8(d.getServiceProviderName());
1015 SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str());
1018 case CA_IDENTIFIER_DESCRIPTOR:
1020 CaIdentifierDescriptor &d = (CaIdentifierDescriptor&)**desc;
1021 const CaSystemIdList &caids = *d.getCaSystemIds();
1022 SCAN_eDebugNoNewLine("CA ");
1023 for (CaSystemIdList::const_iterator i(caids.begin()); i != caids.end(); ++i)
1025 SCAN_eDebugNoNewLine("%04x ", *i);
1026 service->m_ca.push_front(*i);
1032 SCAN_eDebug("descr<%x>", (*desc)->getTag());
1037 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i = m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
1041 m_last_service = i.first;
1042 m_event(evtNewService);
1045 if (m_pmt_running && m_pmt_in_progress->first == service_id)
1046 m_abort_current_pmt = true;
1048 m_pmts_to_read.erase(service_id);
1054 RESULT eDVBScan::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1056 connection = new eConnection(this, m_event.connect(event));
1060 void eDVBScan::getStats(int &transponders_done, int &transponders_total, int &services)
1062 transponders_done = m_ch_scanned.size() + m_ch_unavailable.size();
1063 transponders_total = m_ch_toScan.size() + transponders_done;
1064 services = m_new_services.size();
1067 void eDVBScan::getLastServiceName(std::string &last_service_name)
1069 if (m_last_service == m_new_services.end())
1070 last_service_name = "";
1072 last_service_name = m_last_service->second->m_service_name;
1075 RESULT eDVBScan::getFrontend(ePtr<iDVBFrontend> &fe)
1078 return m_channel->getFrontend(fe);
1083 RESULT eDVBScan::getCurrentTransponder(ePtr<iDVBFrontendParameters> &tp)