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)
43 case 0x13E: // workaround for 11258H and 11470V on hotbird with same ONID/TSID (0x13E/0x578)
44 return orbital_position != 130 || tsid != 0x578;
46 return orbital_position == 192;
48 return tsid != 0x00B0;
50 return tsid != 0x4321;
52 return abs(orbital_position-282) < 6;
54 return onid.get() < 0xFF00;
58 eDVBNamespace eDVBScan::buildNamespace(eOriginalNetworkID onid, eTransportStreamID tsid, unsigned long hash)
60 // on valid ONIDs, ignore frequency ("sub network") part
61 if (isValidONIDTSID((hash >> 16) & 0xFFFF, onid, tsid))
63 return eDVBNamespace(hash);
66 void eDVBScan::stateChange(iDVBChannel *ch)
69 if (ch->getState(state))
71 if (m_channel_state == state)
74 if (state == iDVBChannel::state_ok)
77 m_channel_state = state;
78 } else if (state == iDVBChannel::state_failed)
80 m_ch_unavailable.push_back(m_ch_current);
83 /* unavailable will timeout, anyway. */
86 RESULT eDVBScan::nextChannel()
88 ePtr<iDVBFrontend> fe;
90 m_SDT = 0; m_PAT = 0; m_BAT = 0; m_NIT = 0, m_PMT = 0;
94 m_pat_tsid = eTransportStreamID();
96 /* check what we need */
97 m_ready_all = readySDT;
99 if (m_flags & scanNetworkSearch)
100 m_ready_all |= readyNIT;
102 if (m_flags & scanSearchBAT)
103 m_ready_all |= readyBAT;
106 m_ready_all |= readyPAT;
108 if (m_ch_toScan.empty())
110 SCAN_eDebug("no channels left to scan.");
111 SCAN_eDebug("%d channels scanned, %d were unavailable.",
112 m_ch_scanned.size(), m_ch_unavailable.size());
113 SCAN_eDebug("%d channels in database.", m_new_channels.size());
118 m_ch_current = m_ch_toScan.front();
120 m_ch_toScan.pop_front();
122 if (m_channel->getFrontend(fe))
128 m_chid_current = eDVBChannelID();
130 m_channel_state = iDVBChannel::state_idle;
132 if (fe->tune(*m_ch_current))
133 return nextChannel();
139 RESULT eDVBScan::startFilter()
144 /* only start required filters filter */
146 if (m_ready_all & readyPAT)
147 startSDT = m_ready & readyPAT;
149 // m_ch_current is not set, when eDVBScan is just used for a SDT update
152 unsigned int channelFlags;
153 m_channel->getCurrentFrontendParameters(m_ch_current);
154 m_ch_current->getFlags(channelFlags);
155 if (channelFlags & iDVBFrontendParameters::flagOnlyFree)
156 m_flags |= scanOnlyFree;
160 if (startSDT && (m_ready_all & readySDT))
162 m_SDT = new eTable<ServiceDescriptionSection>(m_scan_debug);
164 if (m_ready & readyPAT && m_ready & validPAT)
166 std::vector<ProgramAssociationSection*>::const_iterator i =
167 m_PAT->getSections().begin();
168 ASSERT(i != m_PAT->getSections().end());
169 tsid = (*i)->getTableIdExtension(); // in PAT this is the transport stream id
170 m_pat_tsid = eTransportStreamID(tsid);
171 for (; i != m_PAT->getSections().end(); ++i)
173 const ProgramAssociationSection &pat = **i;
174 ProgramAssociationConstIterator program = pat.getPrograms()->begin();
175 for (; program != pat.getPrograms()->end(); ++program)
176 m_pmts_to_read.insert(std::pair<unsigned short, service>((*program)->getProgramNumber(), service((*program)->getProgramMapPid())));
178 m_PMT = new eTable<ProgramMapSection>(m_scan_debug);
179 CONNECT(m_PMT->tableReady, eDVBScan::PMTready);
181 // KabelBW HACK ... on 618Mhz and 626Mhz the transport stream id in PAT and SDT is different
185 m_ch_current->getSystem(type);
186 if (type == iDVBFrontend::feCable)
188 eDVBFrontendParametersCable parm;
189 m_ch_current->getDVBC(parm);
190 if ((tsid == 0x00d7 && abs(parm.frequency-618000) < 2000) ||
191 (tsid == 0x00d8 && abs(parm.frequency-626000) < 2000))
198 if (m_SDT->start(m_demux, eDVBSDTSpec()))
201 else if (m_SDT->start(m_demux, eDVBSDTSpec(tsid, true)))
203 CONNECT(m_SDT->tableReady, eDVBScan::SDTready);
206 if (!(m_ready & readyPAT))
209 if (m_ready_all & readyPAT)
211 m_PAT = new eTable<ProgramAssociationSection>(m_scan_debug);
212 if (m_PAT->start(m_demux, eDVBPATSpec(4000)))
214 CONNECT(m_PAT->tableReady, eDVBScan::PATready);
218 if (m_ready_all & readyNIT)
220 m_NIT = new eTable<NetworkInformationSection>(m_scan_debug);
221 if (m_NIT->start(m_demux, eDVBNITSpec()))
223 CONNECT(m_NIT->tableReady, eDVBScan::NITready);
227 if (m_ready_all & readyBAT)
229 m_BAT = new eTable<BouquetAssociationSection>(m_scan_debug);
230 if (m_BAT->start(m_demux, eDVBBATSpec()))
232 CONNECT(m_BAT->tableReady, eDVBScan::BATready);
238 void eDVBScan::SDTready(int err)
240 SCAN_eDebug("got sdt %d", err);
247 void eDVBScan::NITready(int err)
249 SCAN_eDebug("got nit, err %d", err);
256 void eDVBScan::BATready(int err)
258 SCAN_eDebug("got bat");
265 void eDVBScan::PATready(int err)
267 SCAN_eDebug("got pat");
271 startFilter(); // for starting the SDT filter
274 void eDVBScan::PMTready(int err)
276 SCAN_eDebug("got pmt %d", err);
279 bool scrambled = false;
280 bool have_audio = false;
281 bool have_video = false;
282 unsigned short pcrpid = 0xFFFF;
283 std::vector<ProgramMapSection*>::const_iterator i;
284 for (i = m_PMT->getSections().begin(); i != m_PMT->getSections().end(); ++i)
286 const ProgramMapSection &pmt = **i;
287 if (pcrpid == 0xFFFF)
288 pcrpid = pmt.getPcrPid();
290 SCAN_eDebug("already have a pcrpid %04x %04x", pcrpid, pmt.getPcrPid());
291 ElementaryStreamInfoConstIterator es;
292 for (es = pmt.getEsInfo()->begin(); es != pmt.getEsInfo()->end(); ++es)
294 int isaudio = 0, isvideo = 0, is_scrambled = 0;
295 switch ((*es)->getType())
297 case 0x1b: // AVC Video Stream (MPEG4 H264)
298 case 0x01: // MPEG 1 video
299 case 0x02: // MPEG 2 video
301 //break; fall through !!!
302 case 0x03: // MPEG 1 audio
303 case 0x04: // MPEG 2 audio:
306 //break; fall through !!!
307 case 0x06: // PES Private
308 case 0x81: // user private
309 /* PES private can contain AC-3, DTS or lots of other stuff.
310 check descriptors to get the exact type. */
311 for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin();
312 desc != (*es)->getDescriptors()->end(); ++desc)
314 uint8_t tag = (*desc)->getTag();
315 if (!isaudio && !isvideo)
324 case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */
326 /* libdvbsi++ doesn't yet support this descriptor type, so work around. */
327 if ((*desc)->getLength() != 4)
329 unsigned char descr[6];
330 (*desc)->writeToBuffer(descr);
331 int format_identifier = (descr[2] << 24) | (descr[3] << 16) | (descr[4] << 8) | (descr[5]);
332 switch (format_identifier)
343 if (tag == CA_DESCRIPTOR)
357 for (DescriptorConstIterator desc = pmt.getDescriptors()->begin();
358 desc != pmt.getDescriptors()->end(); ++desc)
360 if ((*desc)->getTag() == CA_DESCRIPTOR)
364 m_pmt_in_progress->second.scrambled = scrambled;
366 m_pmt_in_progress->second.serviceType = 1;
367 else if ( have_audio )
368 m_pmt_in_progress->second.serviceType = 2;
370 m_pmt_in_progress->second.serviceType = 100;
372 if (err == -1) // timeout or removed by sdt
373 m_pmts_to_read.erase(m_pmt_in_progress++);
374 else if (m_pmt_running)
378 m_pmt_in_progress = m_pmts_to_read.begin();
379 m_pmt_running = true;
382 if (m_pmt_in_progress != m_pmts_to_read.end())
383 m_PMT->start(m_demux, eDVBPMTSpec(m_pmt_in_progress->second.pmtPid, m_pmt_in_progress->first, 4000));
387 m_pmt_running = false;
393 void eDVBScan::addKnownGoodChannel(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
395 /* add it to the list of known channels. */
397 m_new_channels.insert(std::pair<eDVBChannelID,ePtr<iDVBFrontendParameters> >(chid, feparm));
400 void eDVBScan::addChannelToScan(const eDVBChannelID &chid, iDVBFrontendParameters *feparm)
402 /* check if we don't already have that channel ... */
405 feparm->getSystem(type);
409 case iDVBFrontend::feSatellite:
411 eDVBFrontendParametersSatellite parm;
412 feparm->getDVBS(parm);
413 SCAN_eDebug("try to add %d %d %d %d %d %d",
414 parm.orbital_position, parm.frequency, parm.symbol_rate, parm.polarisation, parm.fec, parm.modulation);
417 case iDVBFrontend::feCable:
419 eDVBFrontendParametersCable parm;
420 feparm->getDVBC(parm);
421 SCAN_eDebug("try to add %d %d %d %d",
422 parm.frequency, parm.symbol_rate, parm.modulation, parm.fec_inner);
425 case iDVBFrontend::feTerrestrial:
427 eDVBFrontendParametersTerrestrial parm;
428 feparm->getDVBT(parm);
429 SCAN_eDebug("try to add %d %d %d %d %d %d %d %d",
430 parm.frequency, parm.modulation, parm.transmission_mode, parm.hierarchy,
431 parm.guard_interval, parm.code_rate_LP, parm.code_rate_HP, parm.bandwidth);
437 /* ... in the list of channels to scan */
438 for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
440 if (sameChannel(*i, feparm))
444 *i = feparm; // update
445 SCAN_eDebug("update");
449 SCAN_eDebug("remove dupe");
450 m_ch_toScan.erase(i++);
460 SCAN_eDebug("already in todo list");
464 /* ... in the list of successfully scanned channels */
465 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_scanned.begin()); i != m_ch_scanned.end(); ++i)
466 if (sameChannel(*i, feparm))
468 SCAN_eDebug("successfully scanned");
472 /* ... in the list of unavailable channels */
473 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator i(m_ch_unavailable.begin()); i != m_ch_unavailable.end(); ++i)
474 if (sameChannel(*i, feparm, true))
476 SCAN_eDebug("scanned but not available");
480 /* ... on the current channel */
481 if (sameChannel(m_ch_current, feparm))
483 SCAN_eDebug("is current");
487 SCAN_eDebug("really add");
488 /* otherwise, add it to the todo list. */
489 m_ch_toScan.push_front(feparm); // better.. then the rotor not turning wild from east to west :)
492 int eDVBScan::sameChannel(iDVBFrontendParameters *ch1, iDVBFrontendParameters *ch2, bool exact) const
495 if (ch1->calculateDifference(ch2, diff, exact))
497 if (diff < 4000) // more than 4mhz difference?
502 void eDVBScan::channelDone()
504 if (m_ready & validSDT && (!(m_flags & scanOnlyFree) || !m_pmt_running))
506 unsigned long hash = 0;
508 m_ch_current->getHash(hash);
510 eDVBNamespace dvbnamespace = buildNamespace(
511 (**m_SDT->getSections().begin()).getOriginalNetworkId(),
512 (**m_SDT->getSections().begin()).getTransportStreamId(),
515 SCAN_eDebug("SDT: ");
516 std::vector<ServiceDescriptionSection*>::const_iterator i;
517 for (i = m_SDT->getSections().begin(); i != m_SDT->getSections().end(); ++i)
518 processSDT(dvbnamespace, **i);
519 m_ready &= ~validSDT;
522 if (m_ready & validNIT)
525 std::list<ePtr<iDVBFrontendParameters> > m_ch_toScan_backup;
526 m_ch_current->getSystem(system);
527 SCAN_eDebug("dumping NIT");
528 if (m_flags & clearToScanOnFirstNIT)
530 m_ch_toScan_backup = m_ch_toScan;
533 std::vector<NetworkInformationSection*>::const_iterator i;
534 for (i = m_NIT->getSections().begin(); i != m_NIT->getSections().end(); ++i)
536 const TransportStreamInfoList &tsinfovec = *(*i)->getTsInfo();
538 for (TransportStreamInfoConstIterator tsinfo(tsinfovec.begin());
539 tsinfo != tsinfovec.end(); ++tsinfo)
541 SCAN_eDebug("TSID: %04x ONID: %04x", (*tsinfo)->getTransportStreamId(),
542 (*tsinfo)->getOriginalNetworkId());
544 eOriginalNetworkID onid = (*tsinfo)->getOriginalNetworkId();
545 eTransportStreamID tsid = (*tsinfo)->getTransportStreamId();
547 for (DescriptorConstIterator desc = (*tsinfo)->getDescriptors()->begin();
548 desc != (*tsinfo)->getDescriptors()->end(); ++desc)
550 switch ((*desc)->getTag())
552 case CABLE_DELIVERY_SYSTEM_DESCRIPTOR:
554 if (system != iDVBFrontend::feCable)
555 break; // when current locked transponder is no cable transponder ignore this descriptor
556 CableDeliverySystemDescriptor &d = (CableDeliverySystemDescriptor&)**desc;
557 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
558 eDVBFrontendParametersCable cable;
560 feparm->setDVBC(cable);
562 unsigned long hash=0;
563 feparm->getHash(hash);
564 eDVBNamespace ns = buildNamespace(onid, tsid, hash);
567 eDVBChannelID(ns, tsid, onid),
571 case TERRESTRIAL_DELIVERY_SYSTEM_DESCRIPTOR:
573 if (system != iDVBFrontend::feTerrestrial)
574 break; // when current locked transponder is no terrestrial transponder ignore this descriptor
575 TerrestrialDeliverySystemDescriptor &d = (TerrestrialDeliverySystemDescriptor&)**desc;
576 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
577 eDVBFrontendParametersTerrestrial terr;
579 feparm->setDVBT(terr);
581 unsigned long hash=0;
582 feparm->getHash(hash);
583 eDVBNamespace ns = buildNamespace(onid, tsid, hash);
586 eDVBChannelID(ns, tsid, onid),
590 case SATELLITE_DELIVERY_SYSTEM_DESCRIPTOR:
592 if (system != iDVBFrontend::feSatellite)
593 break; // when current locked transponder is no satellite transponder ignore this descriptor
595 SatelliteDeliverySystemDescriptor &d = (SatelliteDeliverySystemDescriptor&)**desc;
596 if (d.getFrequency() < 10000)
599 ePtr<eDVBFrontendParameters> feparm = new eDVBFrontendParameters;
600 eDVBFrontendParametersSatellite sat;
603 eDVBFrontendParametersSatellite p;
604 m_ch_current->getDVBS(p);
606 if ( abs(p.orbital_position - sat.orbital_position) < 5 )
607 sat.orbital_position = p.orbital_position;
609 if ( abs(abs(3600 - p.orbital_position) - sat.orbital_position) < 5 )
611 SCAN_eDebug("found transponder with incorrect west/east flag ... correct this");
612 sat.orbital_position = p.orbital_position;
615 feparm->setDVBS(sat);
617 if ( p.orbital_position != sat.orbital_position)
618 SCAN_eDebug("dropping this transponder, it's on another satellite.");
621 unsigned long hash=0;
622 feparm->getHash(hash);
624 eDVBChannelID(buildNamespace(onid, tsid, hash), tsid, onid),
630 SCAN_eDebug("descr<%x>", (*desc)->getTag());
638 /* a pitfall is to have the clearToScanOnFirstNIT-flag set, and having channels which have
639 no or invalid NIT. this code will not erase the toScan list unless at least one valid entry
642 This is not a perfect solution, as the channel could contain a partial NIT. Life's bad.
644 if (m_flags & clearToScanOnFirstNIT)
646 if (m_ch_toScan.empty())
648 eWarning("clearToScanOnFirstNIT was set, but NIT is invalid. Refusing to stop scan.");
649 m_ch_toScan = m_ch_toScan_backup;
651 m_flags &= ~clearToScanOnFirstNIT;
653 m_ready &= ~validNIT;
656 if (m_pmt_running || (m_ready & m_ready_all) != m_ready_all)
658 if (m_abort_current_pmt)
660 m_abort_current_pmt = false;
666 SCAN_eDebug("channel done!");
668 /* if we had services on this channel, we declare
669 this channels as "known good". add it.
671 (TODO: not yet implemented)
672 a NIT entry could have possible overridden
673 our frontend data with more exact data.
675 (TODO: not yet implemented)
676 the tuning process could have lead to more
677 exact data than the user entered.
679 The channel id was probably corrected
680 by the data written in the SDT. this is
681 important, as "initial transponder lists"
682 usually don't have valid CHIDs (and that's
685 These are the reasons for adding the transponder
686 here, and not before.
689 for (m_pmt_in_progress = m_pmts_to_read.begin(); m_pmt_in_progress != m_pmts_to_read.end();)
692 eServiceReferenceDVB ref;
693 ePtr<eDVBService> service = new eDVBService;
697 unsigned long hash = 0;
699 m_ch_current->getHash(hash);
701 m_chid_current = eDVBChannelID(
702 buildNamespace(eOriginalNetworkID(0), m_pat_tsid, hash),
703 m_pat_tsid, eOriginalNetworkID(0));
706 if (m_pmt_in_progress->second.serviceType == 1)
707 SCAN_eDebug("SID %04x is VIDEO", m_pmt_in_progress->first);
708 else if (m_pmt_in_progress->second.serviceType == 2)
709 SCAN_eDebug("SID %04x is AUDIO", m_pmt_in_progress->first);
711 SCAN_eDebug("SID %04x is DATA", m_pmt_in_progress->first);
713 ref.set(m_chid_current);
714 ref.setServiceID(m_pmt_in_progress->first);
715 ref.setServiceType(m_pmt_in_progress->second.serviceType);
717 if (!m_ch_current->getSystem(type))
721 memset(pname, 0, sizeof(pname));
722 memset(sname, 0, sizeof(sname));
725 case iDVBFrontend::feSatellite:
727 eDVBFrontendParametersSatellite parm;
728 m_ch_current->getDVBS(parm);
729 snprintf(sname, 255, "%d%c SID 0x%02x",
731 parm.polarisation ? 'V' : 'H',
732 m_pmt_in_progress->first);
733 snprintf(pname, 255, "%s %s %d%c %d.%d°%c",
734 parm.system ? "DVB-S2" : "DVB-S",
735 parm.modulation == 1 ? "QPSK" : "8PSK",
737 parm.polarisation ? 'V' : 'H',
738 parm.orbital_position/10,
739 parm.orbital_position%10,
740 parm.orbital_position > 0 ? 'E' : 'W');
743 case iDVBFrontend::feTerrestrial:
745 ePtr<iDVBFrontend> fe;
746 eDVBFrontendParametersTerrestrial parm;
747 m_ch_current->getDVBT(parm);
748 snprintf(sname, 255, "%d SID 0x%02x",
750 m_pmt_in_progress->first);
751 if (!m_channel->getFrontend(fe))
753 ePyObject tp_dict = PyDict_New();
754 fe->getTransponderData(tp_dict, false);
755 m_corrected_frequencys[m_chid_current] =
756 PyInt_AsLong(PyDict_GetItemString(tp_dict, "frequency"));
761 case iDVBFrontend::feCable:
763 eDVBFrontendParametersCable parm;
764 m_ch_current->getDVBC(parm);
765 snprintf(sname, 255, "%d SID 0x%02x",
767 m_pmt_in_progress->first);
771 SCAN_eDebug("name '%s', provider_name '%s'", sname, pname);
772 service->m_service_name = convertDVBUTF8(sname);
773 service->genSortName();
774 service->m_provider_name = convertDVBUTF8(pname);
777 if (!(m_flags & scanOnlyFree) || !m_pmt_in_progress->second.scrambled) {
778 SCAN_eDebug("add not scrambled!");
779 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i =
780 m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
783 m_last_service = i.first;
784 m_event(evtNewService);
788 SCAN_eDebug("dont add... is scrambled!");
789 m_pmts_to_read.erase(m_pmt_in_progress++);
793 eWarning("SCAN: the current channel's ID was not corrected - not adding channel.");
795 addKnownGoodChannel(m_chid_current, m_ch_current);
797 m_ch_scanned.push_back(m_ch_current);
799 for (std::list<ePtr<iDVBFrontendParameters> >::iterator i(m_ch_toScan.begin()); i != m_ch_toScan.end();)
801 if (sameChannel(*i, m_ch_current))
803 SCAN_eDebug("remove dupe 2");
804 m_ch_toScan.erase(i++);
813 void eDVBScan::start(const eSmartPtrList<iDVBFrontendParameters> &known_transponders, int flags)
817 m_ch_scanned.clear();
818 m_ch_unavailable.clear();
819 m_new_channels.clear();
820 m_new_services.clear();
821 m_last_service = m_new_services.end();
823 for (eSmartPtrList<iDVBFrontendParameters>::const_iterator i(known_transponders.begin()); i != known_transponders.end(); ++i)
826 for (std::list<ePtr<iDVBFrontendParameters> >::const_iterator ii(m_ch_toScan.begin()); ii != m_ch_toScan.end(); ++ii)
828 if (sameChannel(*i, *ii, true))
835 m_ch_toScan.push_back(*i);
841 void eDVBScan::insertInto(iDVBChannelList *db, bool dontRemoveOldFlags)
843 if (m_flags & scanRemoveServices)
845 bool clearTerrestrial=false;
846 bool clearCable=false;
847 std::set<unsigned int> scanned_sat_positions;
849 std::list<ePtr<iDVBFrontendParameters> >::iterator it(m_ch_scanned.begin());
850 for (;it != m_ch_scanned.end(); ++it)
852 if (m_flags & scanDontRemoveUnscanned)
853 db->removeServices(&(*(*it)));
857 (*it)->getSystem(system);
860 case iDVBFrontend::feSatellite:
862 eDVBFrontendParametersSatellite sat_parm;
863 (*it)->getDVBS(sat_parm);
864 scanned_sat_positions.insert(sat_parm.orbital_position);
867 case iDVBFrontend::feTerrestrial:
869 clearTerrestrial=true;
872 case iDVBFrontend::feCable:
881 for (it=m_ch_unavailable.begin();it != m_ch_unavailable.end(); ++it)
883 if (m_flags & scanDontRemoveUnscanned)
884 db->removeServices(&(*(*it)));
888 (*it)->getSystem(system);
891 case iDVBFrontend::feSatellite:
893 eDVBFrontendParametersSatellite sat_parm;
894 (*it)->getDVBS(sat_parm);
895 scanned_sat_positions.insert(sat_parm.orbital_position);
898 case iDVBFrontend::feTerrestrial:
900 clearTerrestrial=true;
903 case iDVBFrontend::feCable:
912 if (clearTerrestrial)
915 chid.dvbnamespace=0xEEEE0000;
916 db->removeServices(chid);
921 chid.dvbnamespace=0xFFFF0000;
922 db->removeServices(chid);
924 for (std::set<unsigned int>::iterator x(scanned_sat_positions.begin()); x != scanned_sat_positions.end(); ++x)
927 if (m_flags & scanDontRemoveFeeds)
928 chid.dvbnamespace = eDVBNamespace((*x)<<16);
929 // eDebug("remove %d %08x", *x, chid.dvbnamespace.get());
930 db->removeServices(chid, *x);
934 for (std::map<eDVBChannelID, ePtr<iDVBFrontendParameters> >::const_iterator
935 ch(m_new_channels.begin()); ch != m_new_channels.end(); ++ch)
938 ch->second->getSystem(system);
939 if (system == iDVBFrontend::feTerrestrial)
941 std::map<eDVBChannelID, unsigned int>::iterator it = m_corrected_frequencys.find(ch->first);
942 if (it != m_corrected_frequencys.end())
944 eDVBFrontendParameters *p = (eDVBFrontendParameters*)&(*ch->second);
945 eDVBFrontendParametersTerrestrial parm;
947 eDebug("corrected freq for tsid %04x, onid %04x, ns %08x is %d, old was %d",
948 ch->first.transport_stream_id.get(), ch->first.original_network_id.get(),
949 ch->first.dvbnamespace.get(), it->second, parm.frequency);
950 parm.frequency = it->second;
952 m_corrected_frequencys.erase(it);
955 if (m_flags & scanOnlyFree)
957 eDVBFrontendParameters *ptr = (eDVBFrontendParameters*)&(*ch->second);
958 ptr->setFlags(iDVBFrontendParameters::flagOnlyFree);
960 db->addChannelToList(ch->first, ch->second);
963 for (std::map<eServiceReferenceDVB, ePtr<eDVBService> >::const_iterator
964 service(m_new_services.begin()); service != m_new_services.end(); ++service)
966 ePtr<eDVBService> dvb_service;
967 if (!db->getService(service->first, dvb_service))
969 if (dvb_service->m_flags & eDVBService::dxNoSDT)
971 if (!(dvb_service->m_flags & eDVBService::dxHoldName))
973 dvb_service->m_service_name = service->second->m_service_name;
974 dvb_service->m_service_name_sort = service->second->m_service_name_sort;
976 dvb_service->m_provider_name = service->second->m_provider_name;
977 if (service->second->m_ca.size())
978 dvb_service->m_ca = service->second->m_ca;
979 if (!dontRemoveOldFlags) // do not remove new found flags when not wished
980 dvb_service->m_flags &= ~eDVBService::dxNewFound;
984 db->addService(service->first, service->second);
985 if (!(m_flags & scanRemoveServices))
986 service->second->m_flags |= eDVBService::dxNewFound;
991 RESULT eDVBScan::processSDT(eDVBNamespace dvbnamespace, const ServiceDescriptionSection &sdt)
993 const ServiceDescriptionList &services = *sdt.getDescriptions();
994 SCAN_eDebug("ONID: %04x", sdt.getOriginalNetworkId());
995 eDVBChannelID chid(dvbnamespace, sdt.getTransportStreamId(), sdt.getOriginalNetworkId());
997 /* save correct CHID for this channel */
998 m_chid_current = chid;
1000 for (ServiceDescriptionConstIterator s(services.begin()); s != services.end(); ++s)
1002 unsigned short service_id = (*s)->getServiceId();
1003 SCAN_eDebugNoNewLine("SID %04x: ", service_id);
1006 if (m_flags & scanOnlyFree)
1008 std::map<unsigned short, service>::iterator it =
1009 m_pmts_to_read.find(service_id);
1010 if (it != m_pmts_to_read.end())
1012 if (it->second.scrambled)
1014 SCAN_eDebug("is scrambled!");
1018 SCAN_eDebug("is free");
1021 SCAN_eDebug("not found in PAT.. so we assume it is scrambled!!");
1028 eServiceReferenceDVB ref;
1029 ePtr<eDVBService> service = new eDVBService;
1032 ref.setServiceID(service_id);
1034 for (DescriptorConstIterator desc = (*s)->getDescriptors()->begin();
1035 desc != (*s)->getDescriptors()->end(); ++desc)
1037 switch ((*desc)->getTag())
1039 case SERVICE_DESCRIPTOR:
1041 ServiceDescriptor &d = (ServiceDescriptor&)**desc;
1042 ref.setServiceType(d.getServiceType());
1043 service->m_service_name = convertDVBUTF8(d.getServiceName());
1044 service->genSortName();
1046 service->m_provider_name = convertDVBUTF8(d.getServiceProviderName());
1047 SCAN_eDebug("name '%s', provider_name '%s'", service->m_service_name.c_str(), service->m_provider_name.c_str());
1050 case CA_IDENTIFIER_DESCRIPTOR:
1052 CaIdentifierDescriptor &d = (CaIdentifierDescriptor&)**desc;
1053 const CaSystemIdList &caids = *d.getCaSystemIds();
1054 SCAN_eDebugNoNewLine("CA ");
1055 for (CaSystemIdList::const_iterator i(caids.begin()); i != caids.end(); ++i)
1057 SCAN_eDebugNoNewLine("%04x ", *i);
1058 service->m_ca.push_front(*i);
1064 SCAN_eDebug("descr<%x>", (*desc)->getTag());
1069 std::pair<std::map<eServiceReferenceDVB, ePtr<eDVBService> >::iterator, bool> i =
1070 m_new_services.insert(std::pair<eServiceReferenceDVB, ePtr<eDVBService> >(ref, service));
1074 m_last_service = i.first;
1075 m_event(evtNewService);
1078 if (m_pmt_running && m_pmt_in_progress->first == service_id)
1079 m_abort_current_pmt = true;
1081 m_pmts_to_read.erase(service_id);
1087 RESULT eDVBScan::connectEvent(const Slot1<void,int> &event, ePtr<eConnection> &connection)
1089 connection = new eConnection(this, m_event.connect(event));
1093 void eDVBScan::getStats(int &transponders_done, int &transponders_total, int &services)
1095 transponders_done = m_ch_scanned.size() + m_ch_unavailable.size();
1096 transponders_total = m_ch_toScan.size() + transponders_done;
1097 services = m_new_services.size();
1100 void eDVBScan::getLastServiceName(std::string &last_service_name)
1102 if (m_last_service == m_new_services.end())
1103 last_service_name = "";
1105 last_service_name = m_last_service->second->m_service_name;
1108 RESULT eDVBScan::getFrontend(ePtr<iDVBFrontend> &fe)
1111 return m_channel->getFrontend(fe);
1116 RESULT eDVBScan::getCurrentTransponder(ePtr<iDVBFrontendParameters> &tp)